7

The binary directory structure of my project is currently like this (Windows):

bin/mainProject/{Debug,Release}
bin/library1/{Debug,Release}
bin/library2/{Debug,Release}
...
bin/libraryN/{Debug,Release}

I'd like to copy the libraries library1lib.dll, ... libraryNlib.dll to the bin/mainProject/{Debug,Release} directory once they are build.

For CMake, I think this is doable using a post-build event, hence I've tried adding this to each of the libraries' CMakeLists.txt:

add_custom_command(TARGET library1 POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy
        ${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_BUILD_TYPE}/library1lib.dll
        ${CMAKE_BINARY_DIR}/mainProject/${CMAKE_BUILD_TYPE}/
)

Currently, there are two issues:

  1. ${CMAKE_BUILD_TYPE} seems to be not defined, at least I get an empty string for that variable in the output window.
  2. Is there a possibility to make that post-build event more generic? Like replacing the actual dll name with some variable?
user236012
  • 265
  • 1
  • 2
  • 9
  • Highly related and possible dup target: ["_Copy target file to another location in a post build step in CMake_"](https://stackoverflow.com/q/9994045/11107541). – starball Nov 30 '22 at 19:10
  • Also note the existence of the [`RUNTIME_OUTPUT_DIRECTORY`](https://cmake.org/cmake/help/latest/prop_tgt/RUNTIME_OUTPUT_DIRECTORY.html), [`LIBRARY_OUTPUT_DIRECTORY`](https://cmake.org/cmake/help/latest/prop_tgt/LIBRARY_OUTPUT_DIRECTORY.html), and [`ARCHIVE_OUTPUT_DIRECTORY`](https://cmake.org/cmake/help/latest/prop_tgt/ARCHIVE_OUTPUT_DIRECTORY.html) config variables, and the corresponding [`RUNTIME_OUTPUT_DIRECTORY_`](https://cmake.org/cmake/help/latest/prop_tgt/RUNTIME_OUTPUT_DIRECTORY_CONFIG.html), etc. config variables. – starball Nov 30 '22 at 19:12

1 Answers1

8

You can make this more generic by using generator expressions:

add_custom_command(
    TARGET library1 
    POST_BUILD
    COMMAND ${CMAKE_COMMAND} -E copy
        $<TARGET_FILE:library1>
        $<TARGET_FILE_DIR:mainProject>/$<TARGET_FILE_NAME:library1>
)

Alternative

You could - if every dependency is build within your CMake project - also just give a common output path for all executables and DLLs with something like:

set(CMAKE_RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/Out")

Note: The absolute path is required here because it would otherwise be relative to each targets default output path. And note that the configuration's sub-directory is appended by CMake automatically.

References

Florian
  • 39,996
  • 9
  • 133
  • 149
  • It does seem that in many cases CMAKE_RUNTIME_OUTPUT_DIRECTORY will be the appropriate solution. If you're following the so-called "Modern CMake" method of using target properties instead of global variables, you can set the property [RUNTIME_OUTPUT_DIRECTORY](https://cmake.org/cmake/help/latest/prop_tgt/RUNTIME_OUTPUT_DIRECTORY.html) on each target. – Baryons for Breakfast Aug 11 '20 at 04:21