]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - share/mk/bsd.clang-analyze.mk
zfs: merge openzfs/zfs@0ee9b0239
[FreeBSD/FreeBSD.git] / share / mk / bsd.clang-analyze.mk
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
36 CLANG_ANALYZE_OUTPUT?=  text
37 CLANG_ANALYZE_OUTPUT_DIR?=      clang-analyze
38 CLANG_ANALYZE_FLAGS+=   --analyze \
39                         -Xanalyzer -analyzer-output=${CLANG_ANALYZE_OUTPUT} \
40                         -o ${CLANG_ANALYZE_OUTPUT_DIR}
41
42 CLANG_ANALYZE_CHECKERS+=        core deadcode security unix
43 CLANG_ANALYZE_CXX_CHECKERS+=    cplusplus
44
45 .for checker in ${CLANG_ANALYZE_CHECKERS}
46 CLANG_ANALYZE_FLAGS+=   -Xanalyzer -analyzer-checker=${checker}
47 .endfor
48 CLANG_ANALYZE_CXX_FLAGS+=       ${CLANG_ANALYZE_FLAGS}
49 .for checker in ${CLANG_ANALYZE_CXX_CHECKERS}
50 CLANG_ANALYZE_CXX_FLAGS+=       -Xanalyzer -analyzer-checker=${checker}
51 .endfor
52
53 .SUFFIXES: .c .cc .cpp .cxx .C .clang-analyzer
54
55 CLANG_ANALYZE_CFLAGS=   ${CFLAGS:N-Wa,--fatal-warnings}
56 CLANG_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
67 CLANG_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)
73 CLANG_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
85 beforeanalyze: 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)
92 analyze: beforeanalyze .WAIT ${CLANG_ANALYZE_OBJS}
93 .endif
94
95 .if exists(${CLANG_ANALYZE_OUTPUT_DIR})
96 CLEANDIRS+=     ${CLANG_ANALYZE_OUTPUT_DIR}
97 .endif
98
99 .endif  # !target(__<bsd.clang-analyze.mk>__)