2

链接我的程序后,我需要对其进行一些后期处理。我添加了一个add_custom_command(TARGET ...,效果很好。但是,这个额外的自定义命令运行一个脚本(未生成;它已检入代码库),如果该脚本发生更改,我希望将目标视为已过期,以便正确重建它。

add_dependencies规则似乎只在顶级元素之间起作用,这不是(它只是一个脚本),并且没有我可以使用DEPENDS的这种形式的元素。add_custom_command

我该怎么做呢?

4

1 回答 1

2

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:

  1. Compare a previous copy of "my_script" to the current "my_script" in the source tree. If the current "my_script" is different, or if the copy doesn't exist (i.e. this is the first run of CMake) then...
  2. Copy "my_script" from the source tree to the build tree, and...
  3. Touch a source file of the dependent target so that it goes out of date.

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.

于 2013-05-07T00:20:42.097 回答