I have some files that I want to copy to the binary folder (let’s say, data files required for the program to run). I typically build on Windows with Visual Studio, so the copying should support multi-config generators.
My current best approach is with an add_custom_command
in a POST_BUILD
step:
add_custom_command(TARGET mytarget POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_directory
"${CMAKE_CURRENT_SOURCE_DIR}/datadir/"
"$<TARGET_FILE_DIR:mytarget>/datadir")
In principle, this solution works, but it has two issues:
- I havent yet found a way to trigger a project build if only the files in the source datadir have changed. Using the other form of
add_custom_command
withOUTPUT
, as for example proposed here cannot work as far as I see it, since theOUTPUT
cannot contain target-dependent expressions according to the docs (which in my case it would need to; the output location is dependent on the currently active build configuration). - In the form as shown above, it will just blindly copy everytime the build is performed, even if the datadir already exist in the output directory, and the files in the source datadir haven’t changed; I can circumvent this by, instead of just copying, invoking a custom cmake script which checks for the existence of datadir, and whether the files in the source datadir are newer than the ones in the output data dir (though this also is a bit tricky to check for all files in a folder, recursively; I haven’t found a predefined function for this yet?)
The only way I can think of so far of treating problem 1 is to implement basically a minor separate build tool in the script executed at the build step:
- Use OUTPUT form of add_custom_command; specify some intermediate “dummy” file as output
- in the called script:
- use the dummy file as a “map” for last copy times per configuration
- pass in the current configuration (via generator expression)
- check the dummy file for entries for that configuration
- if not present, or if entry is indicating a copy time older than the latest file modification date, copy
This seems a rather common thing to do, so I’m wondering - am I just thinking too complicated or backwards somehow, and there actually is some existing simple way to achieve this?