CMake添加调用clang分析器的目标

Tra*_*s3r 19 c++ cmake clang clang-static-analyzer

我基本上喜欢和http://blog.alexrp.com/2013/09/26/clangs-static-analyzer-and-automake一样,但是使用CMake.

analyze_srcs = foo.c
analyze_plists = $(analyze_srcs:%.c=%.plist)
CLEANFILES = $(analyze_plists)

$(analyze_plists): %.plist: %.c
  @echo "  CCSA  " $@
  @$(COMPILE) --analyze $< -o $@

analyze: $(analyze_plists)
.PHONY: analyze
Run Code Online (Sandbox Code Playgroud)

所以你可以跑

make analyze
make clean
Run Code Online (Sandbox Code Playgroud)

我想我需要使用add_custom_command/add_custom_target并以某种方式更改仅针对该目标的"目标文件"扩展名.

然后获取生成文件的列表,或者将它们传递给脚本,以将它们组合成1个输出文件.

谁能指出我正确的方向?

lar*_*sch 25

你可以scan-build在跑步时使用cmake.

scan-build cmake /path/to/source
scan-build make
Run Code Online (Sandbox Code Playgroud)

scan-build设置拾取的环境变量CCCXX环境变量cmake.

  • 并记得事先擦除CMake缓存(否则命令将无效) (2认同)

K. *_*sky 6

以下解决方案的缺点是编译和分析整个项目,而不是特定目标。

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)
Run Code Online (Sandbox Code Playgroud)

调用它:

cmake --build . --target clang_static_analysis
Run Code Online (Sandbox Code Playgroud)

好处#1:允许自定义工具链工作

scan-build注入CCCXX环境变量来指定替换的编译器,它们是ccc-analyzerc++-analyzer。定义 and 时CMAKE_C_COMPILER,和CMAKE_CXX_COMPILER变量将被忽略。您需要做的就是将变量指向使用环境中的变量(如果已定义)。因此,将其添加到您的工具链文件中:CCCXXscan-buildCMAKE_C*_COMPILER

set(CMAKE_C_COMPILER some/path/to/c_compiler)
set(CMAKE_Cxx_COMPILER some/path/to/cxx_compiler)
Run Code Online (Sandbox Code Playgroud)

将其替换为:

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()
Run Code Online (Sandbox Code Playgroud)

好处#2:使用 LLVM 工具链中的 scan-build

如果您的自定义工具链是 LLVM,那么您很可能希望使用scan-build工具链中的命令。要启用它,只需使用 cmake 的缓存变量定义工具链路径:

set(LLVM_TOOLCHAIN_PATH "some/path/here" CACHE PATH "Path to the LLVM toolchain") 
Run Code Online (Sandbox Code Playgroud)

或从命令行:

cmake -DLLVM_TOOLCHAIN_PATH=some/path/here ...
Run Code Online (Sandbox Code Playgroud)

然后重用自定义目标的路径:

set(scan_build_path ${LLVM_TOOLCHAIN_PATH}/bin/scan-build)
Run Code Online (Sandbox Code Playgroud)

福利 #3:添加测试命令

注意enable_testing必须先调用add_testenable_testing()必须从项目的顶层调用CMakeLists.txt才能ctest解析测试路径。

add_test(
    NAME clang_static_analysis
    COMMAND ${CMAKE_COMMAND} --build . --target clang_static_analysis
)
Run Code Online (Sandbox Code Playgroud)

像这样运行它:

# Fire configure and generate stages
cmake ../source/dir
ctest -R clang_static_analysis --verbose
Run Code Online (Sandbox Code Playgroud)


Tra*_*s3r 5

我找到了一个方法:

function(add_clang_static_analysis target)
    get_target_property(SRCs ${target} SOURCES)
    add_library(${target}_analyze OBJECT EXCLUDE_FROM_ALL ${SRCs})
    set_target_properties(${target}_analyze PROPERTIES
                          COMPILE_OPTIONS "--analyze"
                          EXCLUDE_FROM_DEFAULT_BUILD true)
endfunction()
Run Code Online (Sandbox Code Playgroud)

仍将打开clang的plist文件(以.o扩展名)合并到报告中($<TARGET_OBJECTS:objlibtarget>?)。