如何使ADD_CUSTOM_TARGET仅在依赖文件修改时执行cppcheck?
问题描述
我使用ADD_CUSTOM_TARGET配置Visual Studio解决方案,让编译时自动运行cppcheck:
ADD_CUSTOM_TARGET( STATIC_CODE_ANALYSIS_QUIET ALL COMMAND cppcheck ${PATH_TO_SOURCES}/src )
(以上为最小复现示例,实际使用会添加更多参数)
当前问题:即便src文件夹内的文件未做任何修改,每次构建解决方案时cppcheck都会重复执行,这不符合预期——它应该仅在源文件有改动时才运行。
我尝试过添加DEPENDS参数来指定依赖:
set( STATIC_CODE_ANALYSIS_DEPENDENCIES ) list( APPEND STATIC_CODE_ANALYSIS_DEPENDENCIES "${PATH_TO_SOURCES}/src/main.cpp" ) ADD_CUSTOM_TARGET( STATIC_CODE_ANALYSIS_QUIET ALL COMMAND cppcheck ${PATH_TO_SOURCES}/src DEPENDS ${STATIC_CODE_ANALYSIS_DEPENDENCIES} )
但情况没有任何改善。查阅CMake文档后得知:无输出文件的自定义目标始终会被视为过期状态,这是设计预期行为。
考虑过用add_custom_command来处理更新逻辑,但该命令必须指定OUTPUT参数,而cppcheck本身不会生成输出文件;同时不能使用--output-file将结果写入文件,因为这样会导致Visual Studio控制台无法实时显示输出,而用户需要通过控制台确认工具运行状态。
如何实现:让cppcheck在Visual Studio构建时自动运行,但仅在自上次运行后源文件有修改时才执行?
解决方案
可以通过创建伪输出标记文件的方式解决,既满足add_custom_command对OUTPUT的要求,又能保留cppcheck的控制台输出。具体实现如下:
# 定义用于标记cppcheck上次运行时间的伪输出文件,放在构建目录下 set(CPPCHECK_STAMP_FILE "${CMAKE_BINARY_DIR}/cppcheck_run.stamp") # 自动遍历src目录下所有需要检查的cpp源文件(替代手动添加依赖) file(GLOB_RECURSE STATIC_ANALYSIS_SOURCES "${PATH_TO_SOURCES}/src/*.cpp") # 定义自定义命令:执行cppcheck + 更新标记文件 add_custom_command( OUTPUT ${CPPCHECK_STAMP_FILE} COMMAND cppcheck ${PATH_TO_SOURCES}/src # 保留你实际需要的参数 COMMAND ${CMAKE_COMMAND} -E touch ${CPPCHECK_STAMP_FILE} # 更新标记文件时间戳 DEPENDS ${STATIC_ANALYSIS_SOURCES} COMMENT "Running static code analysis with cppcheck..." ) # 创建自定义目标,依赖伪输出文件 add_custom_target(STATIC_CODE_ANALYSIS_QUIET ALL DEPENDS ${CPPCHECK_STAMP_FILE})
核心原理
add_custom_command会根据DEPENDS中的源文件判断:若源文件有更新,或伪输出文件不存在,则执行命令- cppcheck正常输出到控制台,满足实时查看运行状态的需求
cmake -E touch命令会更新标记文件的时间戳,作为cppcheck已完成运行的标记,确保下次构建仅在源文件改动时重新执行
如果需要更精确的文件筛选,可以调整file(GLOB_RECURSE)的匹配规则,或者手动指定依赖文件列表。
内容的提问来源于stack exchange,提问作者jpo38
相关产品推荐
相关产品推荐

