如何在CMake中仅当源文件存在时执行文件复制操作?
解决CMake自定义命令仅在源文件存在时执行复制的问题
方案1:构建阶段动态判断(推荐,适配源文件后续生成的场景)
利用CMake脚本模式(-P参数),在每次构建前检查源文件是否存在,仅当文件存在时执行复制操作,完美适配「CMake生成项目时源文件不存在、后续构建过程中才生成」的场景。修改后的代码如下:
add_custom_command( TARGET ${PROJECT_NAME} PRE_BUILD COMMAND ${CMAKE_COMMAND} -D SRC="${LIGHT_THEME_SOURCE}" -D DST="${LIGHT_THEME_REF}" -P "${CMAKE_CURRENT_BINARY_DIR}/copy_if_exists.cmake" ) # 自动生成判断复制逻辑的临时脚本 file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/copy_if_exists.cmake" " if(EXISTS \"\${SRC}\") execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different \"\${SRC}\" \"\${DST}\") endif() ")
逻辑说明
- CMake生成项目时,通过
file(WRITE)在构建目录下创建一个临时脚本文件 - 每次执行
PRE_BUILD步骤时,调用这个脚本,脚本内先检查源文件${SRC}是否存在,存在才执行复制命令 - 跨平台兼容性好,无需依赖系统shell的条件语法
方案2:生成阶段静态判断(仅适合源文件在CMake配置时已存在的场景)
如果源文件在CMake运行(生成项目)时就已经存在,或者不需要后续动态检测,可以直接在配置阶段判断是否添加自定义命令:
if(EXISTS ${LIGHT_THEME_SOURCE}) add_custom_command( TARGET ${PROJECT_NAME} PRE_BUILD COMMAND ${CMAKE_COMMAND} ARGS -E copy_if_different ${LIGHT_THEME_SOURCE} "${LIGHT_THEME_REF}" ) endif()
局限性
如果CMake配置时源文件不存在,后续即使文件生成,也不会触发复制——因为自定义命令根本没被添加到构建流程中。
版本兼容说明
两种方案均兼容CMake 3.22版本,无需升级。
内容的提问来源于stack exchange,提问作者ChrisMM
相关产品推荐
相关产品推荐

