# Copying files with destination folder depending on build config

**URL:** https://discourse.cmake.org/t/copying-files-with-destination-folder-depending-on-build-config/10686
**Category:** Usage
**Created:** [April 18, 2024, 10:23am UTC](https://discourse.cmake.org/t/copying-files-with-destination-folder-depending-on-build-config/10686 "2024-04-18T10:23:49Z")
**Posts on this page:** 3
**Page:** 1

<div class="post-metadata">

### Author: ![codeling](https://discourse.cmake.org/user_avatar/discourse.cmake.org/codeling/32/1700_2.png) [@codeling](https://discourse.cmake.org/u/codeling)
#### Post date: [April 18, 2024, 10:23am UTC](https://discourse.cmake.org/t/copying-files-with-destination-folder-depending-on-build-config/10686/1 "2024-04-18T10:23:49Z")

</div>

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:

```auto
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:

1. 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` with `OUTPUT`, as [for example proposed here](https://stackoverflow.com/questions/61947527/how-do-i-make-cmake-re-run-a-add-custom-command-when-a-dependent-file-gets-modif) cannot work as far as I see it, [since the `OUTPUT` cannot contain target-dependent expressions according to the docs](https://cmake.org/cmake/help/latest/command/add_custom_command.html) (which in my case it would need to; the output location is dependent on the currently active build configuration).
2. 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?

---

<div class="post-metadata">

### Author: ![buildSystemPerson](https://discourse.cmake.org/user_avatar/discourse.cmake.org/buildsystemperson/32/2851_2.png) [@buildSystemPerson](https://discourse.cmake.org/u/buildSystemPerson)
#### Post date: [April 19, 2024, 7:07pm UTC](https://discourse.cmake.org/t/copying-files-with-destination-folder-depending-on-build-config/10686/2 "2024-04-19T19:07:31Z")

</div>

In CMake 3.26 there is now [copy\_directory\_if\_different](https://cmake.org/cmake/help/latest/manual/cmake.1.html#cmdoption-cmake-E-arg-copy_directory_if_different).

Instead of using POST\_BUILD which only runs when the target is built; I think a custom target may be more appropriate. Since your data can change without your program having to build.

```auto
add_custom_target(copy_data
	COMMAND ${CMAKE_COMMAND} -E copy_directory_if_different 
        "${CMAKE_CURRENT_SOURCE_DIR}/datadir/"
        "$<TARGET_FILE_DIR:mytarget>/datadir"
    COMMENT "Copying data"
)
add_dependencies(mytarget copy_data)

```

---

<div class="post-metadata">

### Author: ![codeling](https://discourse.cmake.org/user_avatar/discourse.cmake.org/codeling/32/1700_2.png) [@codeling](https://discourse.cmake.org/u/codeling)
#### Post date: [April 24, 2024, 10:01am UTC](https://discourse.cmake.org/t/copying-files-with-destination-folder-depending-on-build-config/10686/3 "2024-04-24T10:01:09Z")

</div>

It’s working nicely, thanks!

The only (minor) downside is that there now is an additional project cluttering the workspace for every such copying task (e.g. when using Visual Studio generator; there I “hide” them in a common folder).
