Existing solutions suggest using add_custom_command
, and that works, but I consider it ugly and error prone, so I wonder if there is a way when I declare my 3rdparty library to say that any executable using my library should have dll copied to where executable is built. Obviously support for different dlls in Release/Debug is also necessary.

- 28,205
- 28
- 128
- 277
-
1I don't think that CMake supports "auto-copy" feature for the library. A declarative way would be adding the directory with `.dll` to the PATH environment variable once the library is installed. – Tsyvarev Jul 15 '21 at 13:04
-
1The vcpkg toolchain patches `add_executable` and `add_library` to do this. – Alex Reinking Jul 15 '21 at 19:33
-
@AlexReinking interesting, I thought add_executable and add_library are "builtin"s. do you have link to docs about this, i do not use vcpkg, but maybe I can use their methods – NoSenseEtAl Jul 15 '21 at 23:41
-
1[Here](https://github.com/microsoft/vcpkg/blob/e43557e6652f0c7713e5a6f07fd7d5ac6153f580/scripts/buildsystems/vcpkg.cmake#L544) is where it overrides `add_executable`. Look at the `VCPKG_APPLOCAL_DEPS` branch... it adds a `POST_BUILD` custom command which calls [this PowerShell script](https://github.com/microsoft/vcpkg/blob/e43557e6652f0c7713e5a6f07fd7d5ac6153f580/scripts/buildsystems/msbuild/applocal.ps1). – Alex Reinking Jul 16 '21 at 00:26
-
@AlexReinking thank you, you can make it an answer, although it is a bit too complex for me to understand it technically does what I want. :) – NoSenseEtAl Jul 16 '21 at 00:37
-
@NoSenseEtAl If you post a more complete example, I am sure we can provide more specific answers. – bremen_matt Jul 16 '21 at 07:56
1 Answers
You are clearly on Windows since you are building dll's. But on Linux I would just comment that one can set the RPATH for a binary. In Cmake this looks something like
set_target_properties(target PROPERTIES INSTALL_RPATH ${path_to_libs})
# Maybe also this line...
target_link_libraries(target PUBLIC -Wl,--disable-new-dtags)
I have no idea what effect this has in Windows. However, in Linux this basically tells the binary where to look for libraries that it will need to link to, thus avoiding the need to either copy the libraries to the same directory or to copy the libraries to the standard library path.
If you have a target A in Cmake, and you either export that target, or include it in another Cmake project as a subdirectory (via add_subdirectory), then you could easily just bundle all of the shared libraries together into the target like this:
CMakeLists.txt for target A:
add_library(A ... )
target_link_libraries(A PUBLIC other_libs_needed_by_consumers_of_A)
CMakeLists.txt for target B:
target_link_libraries(B PUBLIC A)

- 6,902
- 7
- 42
- 90
-
2"I have no idea what effect this has in Windows." - Setting RPATH has **no effect** on Windows: This OS doesn't support embedding library search paths into the binaries. As for the property `INSTALL_RPATH`, it affects **only on the target itself**. This property is NOT consumed by one who links with your library. – Tsyvarev Jul 15 '21 at 16:09
-
1By the way, on Windows copying `.dll` near the executable is needed only for **build tree**: For installing, there is module [BundleUtilities](https://cmake.org/cmake/help/latest/module/BundleUtilities.html) which (as far as I understand) could add all **used** dlls into the installation tree. But setting `INSTALL_RPATH` on Linux helps only for **installing**. For binary tree CMake adds all needed RPATH's automatically (this is default behavior). – Tsyvarev Jul 15 '21 at 16:21