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