CMake: How to have a target for copying files

2019-01-17 23:49发布

问题:

I am using the following command to copy config files into the build directory after each compile.

# Gather list of all .xml and .conf files in "/config"
file(GLOB ConfigFiles ${CMAKE_SOURCE_DIR}/config/*.xml
                      ${CMAKE_SOURCE_DIR}/config/*.conf)

foreach(ConfigFile ${ConfigFiles})
  add_custom_command(TARGET MyTarget PRE_BUILD
                     COMMAND ${CMAKE_COMMAND} -E
                         copy ${ConfigFile} $<TARGET_FILE_DIR:MyTarget>)
endforeach()

This action is triggered every time I compile the project. Is it possible to create a target in CMakeLists.txt to copy files without needing to compile anything? Something like "make copy".

回答1:

You should be able to add a new custom target called copy and make that the target of your custom commands:

file(GLOB ConfigFiles ${CMAKE_SOURCE_DIR}/config/*.xml
                      ${CMAKE_SOURCE_DIR}/config/*.conf)

add_custom_target(copy)
foreach(ConfigFile ${ConfigFiles})
  add_custom_command(TARGET copy PRE_BUILD
                     COMMAND ${CMAKE_COMMAND} -E
                         copy ${ConfigFile} $<TARGET_FILE_DIR:MyTarget>)
endforeach()

Now the custom commands will only execute if you build copy.

If you want to keep this copy target as a dependency of MyTarget so that you can either just copy the files or have them copied if you build MyTarget, you'll need to break the cyclic dependency. (MyTarget depends on copy, but copy depends on MyTarget to get the location of the copy-to directory).

To do this, you can resort to the old-fashioned way of getting a target's output directory:

add_custom_target(copy)
get_target_property(MyTargetLocation MyTarget LOCATION)
get_filename_component(MyTargetDir ${MyTargetLocation} PATH)
foreach(ConfigFile ${ConfigFiles})
  add_custom_command(TARGET copy PRE_BUILD
                     COMMAND ${CMAKE_COMMAND} -E
                         copy ${ConfigFile} ${MyTargetDir})
endforeach()
add_dependencies(MyTarget copy)


标签: cmake