Over the decades, a lot has been written about associating a DLL with an executable and getting that DLL into install directories, or getting that DLL into ctest directories.
I’m trying to modernize a 14 year old CMakeLists based project, and several targets end up needing an out-of-tree built imported.dll
(fmod if you need a concrete example), which is linked against through a low-level internal library, that other internal libs link against, and ultimately targets innocently acquire.
wrapper(links dependency) ← lib1(links wrapper) ← lib2(links lib1) ← exe(links lib2)
This was an early component of the projects so … it’s done with includes, variables, and a"post build" function that uses copy_if_different but has to be called by every target that ends up using sound.
EDIT:
I’ve created a small demo repository for this: GitHub - kfsone/cmake-dlldep: Demonstrate how to implement a dll dependency in cmake
What I want to achieve:
- .dll files automatically copied by down-stream “install()” calls,
- .dll files automatically copy alongside their .exe in the build tree,
- no function calls or variable use after the definition of target that links the dll’s .lib,
I imagine the code being something like:
add_library(DependentDLL SHARED IMPORT)
set_target_properties(DependentDLL PROPERTIES ... $<secretsauce> dep.dll)
add_library(lib1 lib1.cpp)
target_link_libraries(lib1 PUBLIC DependentDLL)
add_library(lib2 lib2.cpp)
target_link_libraries(lib2 PUBLIC lib1)
add_executable(program program.cpp)
target_link_libraries(program lib2)
install(TARGETS program DESTINATION ${INSTALL_PATH} COMPONENT program)
So executing:
$ cmake -G Ninja -B ${build_dir} -DCMAKE_PREFIX_PATH=${tmpdir}
$ cmake --build ${build_dir} --target program
$ cmake --install ${build_dir} --component program
must result in the following files:
- ${build_exe_dir}/program.exe
- ${build_exe_dir}/dep.dll
- ${tmpdir}/program.exe
- ${tmpdir}/dep.dll
Is this something that can be done cleanly, i.e without having to trawl GET_RUNTIME_DEPENDENCIES
or invoke ADD_CUSTOM_COMMAND
(directly or indirectly) downstream of the actual linkage?
Also, based on the amount of conflicting and confusing stack/quora/etc posts about this it seems something worth documenting with examples in the cmake docs.