2016-02-26 22:14:00 +00:00
|
|
|
#
|
|
|
|
# Support Clang static analyzer on SRCS.
|
|
|
|
#
|
|
|
|
#
|
|
|
|
# +++ variables +++
|
|
|
|
#
|
|
|
|
# CLANG_ANALYZE_CHECKERS Which checkers to run for all sources.
|
|
|
|
#
|
|
|
|
# CLANG_ANALYZE_CXX_CHECKERS Which checkers to run for C++ sources.
|
|
|
|
#
|
|
|
|
# CLANG_ANALYZE_OUTPUT Output format for generated files.
|
|
|
|
# text - don't generate extra files.
|
|
|
|
# html - generate html in obj.plist/ directories.
|
|
|
|
# plist - generate xml obj.plist files.
|
|
|
|
# See also:
|
2019-12-20 19:53:05 +00:00
|
|
|
# contrib/llvm-project/clang/include/clang/StaticAnalyzer/Core/Analyses.def
|
2016-02-26 22:14:00 +00:00
|
|
|
#
|
|
|
|
# CLANG_ANALYZE_OUTPUT_DIR Sets which directory output set by
|
|
|
|
# CLANG_ANALYZE_OUTPUT is placed into.
|
|
|
|
#
|
|
|
|
# +++ targets +++
|
|
|
|
#
|
|
|
|
# analyze:
|
|
|
|
# Run the Clang static analyzer against all sources and present
|
|
|
|
# output on stdout.
|
|
|
|
|
|
|
|
.if !target(__<bsd.clang-analyze.mk>__)
|
|
|
|
__<bsd.clang-analyze.mk>__:
|
|
|
|
|
|
|
|
.include <bsd.compiler.mk>
|
|
|
|
|
|
|
|
.if ${COMPILER_TYPE} != "clang" && (make(analyze) || make(*.clang-analyzer))
|
|
|
|
.error Clang static analyzer requires clang but found that compiler '${CC}' is ${COMPILER_TYPE}
|
|
|
|
.endif
|
|
|
|
|
|
|
|
CLANG_ANALYZE_OUTPUT?= text
|
|
|
|
CLANG_ANALYZE_OUTPUT_DIR?= clang-analyze
|
|
|
|
CLANG_ANALYZE_FLAGS+= --analyze \
|
|
|
|
-Xanalyzer -analyzer-output=${CLANG_ANALYZE_OUTPUT} \
|
|
|
|
-o ${CLANG_ANALYZE_OUTPUT_DIR}
|
|
|
|
|
|
|
|
CLANG_ANALYZE_CHECKERS+= core deadcode security unix
|
|
|
|
CLANG_ANALYZE_CXX_CHECKERS+= cplusplus
|
|
|
|
|
|
|
|
.for checker in ${CLANG_ANALYZE_CHECKERS}
|
|
|
|
CLANG_ANALYZE_FLAGS+= -Xanalyzer -analyzer-checker=${checker}
|
|
|
|
.endfor
|
|
|
|
CLANG_ANALYZE_CXX_FLAGS+= ${CLANG_ANALYZE_FLAGS}
|
|
|
|
.for checker in ${CLANG_ANALYZE_CXX_CHECKERS}
|
|
|
|
CLANG_ANALYZE_CXX_FLAGS+= -Xanalyzer -analyzer-checker=${checker}
|
|
|
|
.endfor
|
|
|
|
|
|
|
|
.SUFFIXES: .c .cc .cpp .cxx .C .clang-analyzer
|
|
|
|
|
|
|
|
CLANG_ANALYZE_CFLAGS= ${CFLAGS:N-Wa,--fatal-warnings}
|
|
|
|
CLANG_ANALYZE_CXXFLAGS= ${CXXFLAGS:N-Wa,--fatal-warnings}
|
|
|
|
|
|
|
|
.c.clang-analyzer:
|
|
|
|
${CC:N${CCACHE_BIN}} ${CLANG_ANALYZE_FLAGS} \
|
2016-03-26 03:46:04 +00:00
|
|
|
${CLANG_ANALYZE_CFLAGS} \
|
|
|
|
${.IMPSRC}
|
2016-02-26 22:14:00 +00:00
|
|
|
.cc.clang-analyzer .cpp.clang-analyzer .cxx.clang-analyzer .C.clang-analyzer:
|
|
|
|
${CXX:N${CCACHE_BIN}} ${CLANG_ANALYZE_CXX_FLAGS} \
|
2016-03-26 03:46:04 +00:00
|
|
|
${CLANG_ANALYZE_CXXFLAGS} \
|
|
|
|
${.IMPSRC}
|
2016-02-26 22:14:00 +00:00
|
|
|
|
|
|
|
CLANG_ANALYZE_SRCS= \
|
|
|
|
${SRCS:M*.[cC]} ${SRCS:M*.cc} \
|
|
|
|
${SRCS:M*.cpp} ${SRCS:M*.cxx} \
|
|
|
|
${DPSRCS:M*.[cC]} ${DPSRCS:M*.cc} \
|
|
|
|
${DPSRCS:M*.cpp} ${DPSRCS:M*.cxx}
|
|
|
|
.if !empty(CLANG_ANALYZE_SRCS)
|
2017-11-10 08:00:09 +00:00
|
|
|
CLANG_ANALYZE_OBJS= ${CLANG_ANALYZE_SRCS:O:u:${OBJS_SRCS_FILTER:ts:}:S,$,.clang-analyzer,}
|
2016-02-26 22:14:00 +00:00
|
|
|
.NOPATH: ${CLANG_ANALYZE_OBJS}
|
|
|
|
.endif
|
|
|
|
|
|
|
|
# .depend files aren't relevant here since they reference obj.o rather than
|
|
|
|
# obj.clang-analyzer, so add in some guesses in case 'make depend' wasn't ran,
|
|
|
|
# for when directly building 'obj.clang-analyzer'.
|
|
|
|
.for __obj in ${CLANG_ANALYZE_OBJS}
|
|
|
|
${__obj}: ${OBJS_DEPEND_GUESS}
|
|
|
|
${__obj}: ${OBJS_DEPEND_GUESS.${__obj}}
|
|
|
|
.endfor
|
|
|
|
|
2016-03-30 23:50:23 +00:00
|
|
|
beforeanalyze: depend .PHONY
|
2016-02-26 22:14:00 +00:00
|
|
|
.if !defined(_RECURSING_PROGS) && !empty(CLANG_ANALYZE_SRCS) && \
|
|
|
|
${CLANG_ANALYZE_OUTPUT} != "text"
|
|
|
|
mkdir -p ${CLANG_ANALYZE_OUTPUT_DIR}
|
|
|
|
.endif
|
|
|
|
|
|
|
|
.if !target(analyze)
|
|
|
|
analyze: beforeanalyze .WAIT ${CLANG_ANALYZE_OBJS}
|
|
|
|
.endif
|
|
|
|
|
|
|
|
.if exists(${CLANG_ANALYZE_OUTPUT_DIR})
|
|
|
|
CLEANDIRS+= ${CLANG_ANALYZE_OUTPUT_DIR}
|
|
|
|
.endif
|
|
|
|
|
|
|
|
.endif # !target(__<bsd.clang-analyze.mk>__)
|