链接我的程序后,我需要对其进行一些后期处理。我添加了一个add_custom_command(TARGET ...
,效果很好。但是,这个额外的自定义命令运行一个脚本(未生成;它已检入代码库),如果该脚本发生更改,我希望将目标视为已过期,以便正确重建它。
该add_dependencies
规则似乎只在顶级元素之间起作用,这不是(它只是一个脚本),并且没有我可以使用DEPENDS
的这种形式的元素。add_custom_command
我该怎么做呢?
链接我的程序后,我需要对其进行一些后期处理。我添加了一个add_custom_command(TARGET ...
,效果很好。但是,这个额外的自定义命令运行一个脚本(未生成;它已检入代码库),如果该脚本发生更改,我希望将目标视为已过期,以便正确重建它。
该add_dependencies
规则似乎只在顶级元素之间起作用,这不是(它只是一个脚本),并且没有我可以使用DEPENDS
的这种形式的元素。add_custom_command
我该怎么做呢?
It's unfortunately a bit convoluted, but you can use add_custom_target
to invoke CMake in script-processing mode via -P
.
You need to use add_custom_target
here since it will always execute, even if everything's up to date.
Having made this decision, we need to have the custom target execute commands which will check for a new version of your post-processing script file (let's call this "my_script" and assume it's in your root dir), and if it's changed cause your dependent target to go out of date.
This would comprise:
All of the commands required inside the CMake script can be achieved using execute_process
to invoke cmake -E
.
So the CMake script (called e.g. "copy_script.cmake") would be something like:
execute_process(COMMAND ${CMAKE_COMMAND} -E compare_files
${OriginalScript} ${CopiedScript} RESULT_VARIABLE Result)
if(Result)
execute_process(COMMAND ${CMAKE_COMMAND} -E copy
${OriginalScript} ${CopiedScript})
execute_process(COMMAND ${CMAKE_COMMAND} -E touch_nocreate ${FileToTouch})
endif()
The CMake script needs to have required variables passed in via the -D
args before calling -P
, so the calling CMakeLists.txt would have something like:
set(FileToTouch ${CMAKE_SOURCE_DIR}/src/main.cpp)
add_custom_target(CopyScript ALL ${CMAKE_COMMAND}
-DOriginalScript=${CMAKE_SOURCE_DIR}/my_script
-DCopiedScript=${CMAKE_BINARY_DIR}/my_script
-DFileToTouch=${FileToTouch}
-P ${CMAKE_SOURCE_DIR}/copy_script.cmake)
add_executable(MyExe ${FileToTouch})
This will cause a full rebuild of the executable, since it thinks a source file has been modified. If you only require to force relinking there may be a better way to achieve this.