以下解决方案的缺点是编译和分析整个项目,而不是具体目标。
set(on_side_build_path ${CMAKE_BINARY_DIR}/clang_static_analysis)
set(scan_build_path scan-build)
set(reports_path ${CMAKE_BINARY_DIR}/clang_static_analysis_reports)
# Creates clean directory where the analysis will be built.
add_custom_target(clang_static_analysis_prepare
COMMAND ${CMAKE_COMMAND} -E rm -rf ${on_side_build_path}
COMMAND ${CMAKE_COMMAND} -E make_directory ${on_side_build_path}
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
)
# Runs the analysis from the path created specifically for that task. Use 'my own' project source directory as the source directory.
add_custom_target(clang_static_analysis
# scan-build wants Debug build, for better analysis.
COMMAND ${scan_build_path} ${CMAKE_COMMAND} ${CMAKE_SOURCE_DIR} -DCMAKE_BUILD_TYPE=Debug
COMMAND ${scan_build_path}
-v -v -o ${reports_path}
${CMAKE_COMMAND} --build .
WORKING_DIRECTORY ${on_side_build_path}
)
# Run the *_prepare target always before the analysis
add_dependencies(clang_static_analysis clang_static_analysis_prepare)
调用它:
cmake --build . --target clang_static_analysis
奖励 #1:允许自定义工具链工作
scan-build
注入CC
和CXX
环境变量以指定替换的编译器,即ccc-analyzer
和c++-analyzer
。定义时和CMAKE_C_COMPILER
变量将被忽略。您需要做的支持是指向变量以使用来自环境的变量(如果已定义)。所以在你的工具链文件中有这个:CMAKE_CXX_COMPILER
CC
CXX
scan-build
CMAKE_C*_COMPILER
set(CMAKE_C_COMPILER some/path/to/c_compiler)
set(CMAKE_Cxx_COMPILER some/path/to/cxx_compiler)
将其替换为:
if(DEFINED ENV{CC})
set(CMAKE_C_COMPILER $ENV{CC})
else()
set(CMAKE_C_COMPILER some/path/to/c_compiler)
endif()
if(DEFINED ENV{CXX})
set(CMAKE_CXX_COMPILER $ENV{CXX})
else()
set(CMAKE_CXX_COMPILER some/path/to/cxx_compiler)
endif()
奖励 #2:使用 LLVM 工具链中的 scan-build
如果您的自定义工具链是 LLVM,那么您很可能想要使用scan-build
工具链中的命令。要启用它,只需使用 cmake 的缓存变量定义工具链路径的路径:
set(LLVM_TOOLCHAIN_PATH "some/path/here" CACHE PATH "Path to the LLVM toolchain")
或从命令行:
cmake -DLLVM_TOOLCHAIN_PATH=some/path/here ...
然后重用来自自定义目标的路径:
set(scan_build_path ${LLVM_TOOLCHAIN_PATH}/bin/scan-build)
奖励 #3:添加测试命令
注:enable_testing
须先调用add_test
。enable_testing()
必须从项目的顶层调用CMakeLists.txt
forctest
来解析测试路径。
add_test(
NAME clang_static_analysis
COMMAND ${CMAKE_COMMAND} --build . --target clang_static_analysis
)
像这样运行它:
# Fire configure and generate stages
cmake ../source/dir
ctest -R clang_static_analysis --verbose