Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CMake: How to have a target for copying files

Tags:

cmake

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".

like image 477
B Faley Avatar asked Jan 23 '13 07:01

B Faley


People also ask

How do I add a target in CMake?

Adds a target with the given name that executes the given commands. The target has no output file and is always considered out of date even if the commands try to create a file with the name of the target. Use the add_custom_command() command to generate a file with dependencies.


1 Answers

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)
like image 126
Fraser Avatar answered Oct 05 '22 22:10

Fraser