如何通过CMake配置让Cppcheck跳过第三方库源码分析?
问题描述
我维护着一个大型代码库,包含现代C++、有30多年历史的传统C++(MFC),还有Boost、range-v3、Catch2等第三方库,通过CMake构建,支持Windows、Linux(x86/ARM)平台。我用Cppcheck做现代代码的静态分析,但启用后大量时间都浪费在第三方库的.cpp文件分析上。
第三方库通过FetchContent引入,示例代码:
Include(FetchContent) FetchContent_Declare( Catch2 GIT_REPOSITORY https://github.com/catchorg/Catch2.git GIT_TAG v3.0.1 SYSTEM ) FetchContent_MakeAvailable(Catch2)
当前Cppcheck配置:
set(CMAKE_CXX_CPPCHECK --suppress=missingInclude --suppress=missingIncludeSystem --suppress=unusedFunction --suppress=unmatchedSuppression --suppress=functionStatic --suppress=funcArgNamesDifferent --suppress=*:*_deps/* --enable=all --inline-suppr --inconclusive --force -i ${CMAKE_SOURCE_DIR}/imgui/lib )
其中_deps是第三方库拉取、构建的目录,当前的--suppress=*:*_deps/*只禁用了头文件的告警,没法阻止Cppcheck分析第三方库的源码文件。想知道怎么彻底阻止Cppcheck分析第三方库,是否可以在FetchContent的代码段里临时清空CMAKE_CXX_CPPCHECK,调用完再恢复?
解决方案
方法1:临时修改CMAKE_CXX_CPPCHECK(你说的方案完全可行)
可以在拉取、构建第三方库前后,临时保存、清空、恢复CMAKE_CXX_CPPCHECK,让第三方库的构建过程完全不触发Cppcheck:
# 保存当前的Cppcheck配置 set(ORIGINAL_CPPCHECK ${CMAKE_CXX_CPPCHECK}) # 清空配置,禁止第三方库构建时运行Cppcheck set(CMAKE_CXX_CPPCHECK "") Include(FetchContent) FetchContent_Declare( Catch2 GIT_REPOSITORY https://github.com/catchorg/Catch2.git GIT_TAG v3.0.1 SYSTEM ) FetchContent_MakeAvailable(Catch2) # 恢复原来的Cppcheck配置 set(CMAKE_CXX_CPPCHECK ${ORIGINAL_CPPCHECK})
这个方法直接切断了第三方库构建阶段的Cppcheck调用,是最直接有效的方式。
方法2:用Cppcheck的排除参数精准跳过_deps目录
你当前的--suppress只是抑制告警,但没跳过文件分析。可以改用Cppcheck的-e(排除)参数,直接排除整个_deps目录:
修改CMAKE_CXX_CPPCHECK配置,新增-e ${CMAKE_BINARY_DIR}/_deps:
set(CMAKE_CXX_CPPCHECK --suppress=missingInclude --suppress=missingIncludeSystem --suppress=unusedFunction --suppress=unmatchedSuppression --suppress=functionStatic --suppress=funcArgNamesDifferent --enable=all --inline-suppr --inconclusive --force -i ${CMAKE_SOURCE_DIR}/imgui/lib -e ${CMAKE_BINARY_DIR}/_deps # 新增:排除整个_deps目录 )
注意这里要用CMAKE_BINARY_DIR,因为_deps是在构建目录下生成的,不是源码目录。
方法3:针对第三方库目标单独禁用Cppcheck
对于已经通过FetchContent引入的库,可以给它的目标设置CXX_CPPCHECK为空,覆盖全局配置:
FetchContent_MakeAvailable(Catch2) # 禁用Catch2目标的Cppcheck分析 set_target_properties(Catch2 PROPERTIES CXX_CPPCHECK "") # 如果有子目标(比如Catch2WithMain),也需要单独设置 set_target_properties(Catch2WithMain PROPERTIES CXX_CPPCHECK "")
这个方法更精细化,适合只针对特定几个第三方库禁用的场景。
内容的提问来源于stack exchange,提问作者mark

