1# $FreeBSD$ 2# 3# Support Clang static analyzer on SRCS. 4# 5# 6# +++ variables +++ 7# 8# CLANG_ANALYZE_CHECKERS Which checkers to run for all sources. 9# 10# CLANG_ANALYZE_CXX_CHECKERS Which checkers to run for C++ sources. 11# 12# CLANG_ANALYZE_OUTPUT Output format for generated files. 13# text - don't generate extra files. 14# html - generate html in obj.plist/ directories. 15# plist - generate xml obj.plist files. 16# See also: 17# contrib/llvm/tools/clang/include/clang/StaticAnalyzer/Core/Analyses.def 18# 19# CLANG_ANALYZE_OUTPUT_DIR Sets which directory output set by 20# CLANG_ANALYZE_OUTPUT is placed into. 21# 22# +++ targets +++ 23# 24# analyze: 25# Run the Clang static analyzer against all sources and present 26# output on stdout. 27 28.if !target(__<bsd.clang-analyze.mk>__) 29__<bsd.clang-analyze.mk>__: 30 31.include <bsd.compiler.mk> 32 33.if ${COMPILER_TYPE} != "clang" && (make(analyze) || make(*.clang-analyzer)) 34.error Clang static analyzer requires clang but found that compiler '${CC}' is ${COMPILER_TYPE} 35.endif 36 37CLANG_ANALYZE_OUTPUT?= text 38CLANG_ANALYZE_OUTPUT_DIR?= clang-analyze 39CLANG_ANALYZE_FLAGS+= --analyze \ 40 -Xanalyzer -analyzer-output=${CLANG_ANALYZE_OUTPUT} \ 41 -o ${CLANG_ANALYZE_OUTPUT_DIR} 42 43CLANG_ANALYZE_CHECKERS+= core deadcode security unix 44CLANG_ANALYZE_CXX_CHECKERS+= cplusplus 45 46.for checker in ${CLANG_ANALYZE_CHECKERS} 47CLANG_ANALYZE_FLAGS+= -Xanalyzer -analyzer-checker=${checker} 48.endfor 49CLANG_ANALYZE_CXX_FLAGS+= ${CLANG_ANALYZE_FLAGS} 50.for checker in ${CLANG_ANALYZE_CXX_CHECKERS} 51CLANG_ANALYZE_CXX_FLAGS+= -Xanalyzer -analyzer-checker=${checker} 52.endfor 53 54.SUFFIXES: .c .cc .cpp .cxx .C .clang-analyzer 55 56CLANG_ANALYZE_CFLAGS= ${CFLAGS:N-Wa,--fatal-warnings} 57CLANG_ANALYZE_CXXFLAGS= ${CXXFLAGS:N-Wa,--fatal-warnings} 58 59.c.clang-analyzer: 60 ${CC:N${CCACHE_BIN}} ${CLANG_ANALYZE_FLAGS} \ 61 ${CLANG_ANALYZE_CFLAGS} ${CPPFLAGS} \ 62 ${COPTS.${.IMPSRC:T}} ${CPUFLAGS.${.IMPSRC:T}} \ 63 ${CPPFLAGS.${.IMPSRC:T}} ${.IMPSRC} 64.cc.clang-analyzer .cpp.clang-analyzer .cxx.clang-analyzer .C.clang-analyzer: 65 ${CXX:N${CCACHE_BIN}} ${CLANG_ANALYZE_CXX_FLAGS} \ 66 ${CLANG_ANALYZE_CXXFLAGS} ${CPPFLAGS} \ 67 ${COPTS.${.IMPSRC:T}} ${CPUFLAGS.${.IMPSRC:T}} \ 68 ${CPPFLAGS.${.IMPSRC:T}} ${.IMPSRC} 69 70CLANG_ANALYZE_SRCS= \ 71 ${SRCS:M*.[cC]} ${SRCS:M*.cc} \ 72 ${SRCS:M*.cpp} ${SRCS:M*.cxx} \ 73 ${DPSRCS:M*.[cC]} ${DPSRCS:M*.cc} \ 74 ${DPSRCS:M*.cpp} ${DPSRCS:M*.cxx} 75.if !empty(CLANG_ANALYZE_SRCS) 76CLANG_ANALYZE_OBJS= ${CLANG_ANALYZE_SRCS:O:u:R:S,$,.clang-analyzer,} 77.NOPATH: ${CLANG_ANALYZE_OBJS} 78.endif 79 80# .depend files aren't relevant here since they reference obj.o rather than 81# obj.clang-analyzer, so add in some guesses in case 'make depend' wasn't ran, 82# for when directly building 'obj.clang-analyzer'. 83.for __obj in ${CLANG_ANALYZE_OBJS} 84${__obj}: ${OBJS_DEPEND_GUESS} 85${__obj}: ${OBJS_DEPEND_GUESS.${__obj}} 86.endfor 87 88.if ${MK_FAST_DEPEND} == "yes" 89beforeanalyze: depend 90.endif 91beforeanalyze: .PHONY 92.if !defined(_RECURSING_PROGS) && !empty(CLANG_ANALYZE_SRCS) && \ 93 ${CLANG_ANALYZE_OUTPUT} != "text" 94 mkdir -p ${CLANG_ANALYZE_OUTPUT_DIR} 95.endif 96 97.if !target(analyze) 98analyze: beforeanalyze .WAIT ${CLANG_ANALYZE_OBJS} 99.endif 100 101.if exists(${CLANG_ANALYZE_OUTPUT_DIR}) 102CLEANDIRS+= ${CLANG_ANALYZE_OUTPUT_DIR} 103.endif 104 105.endif # !target(__<bsd.clang-analyze.mk>__) 106