'CMake - How to handle dependencies of imported library targets with TARGET_RUNTIME_DLLS
In my project I rely on some third party shared library named foo
.
foo
itself is relying on some other third party dll (let's call it bar.dll
), which is however neither used by my project nor exposed in the headers of foo
.
The foo
target is created and linked to my project as follows
add_library(foo SHARED IMPORTED)
set_target_properties(foo PROPERTIES
IMPORTED_LOCATION "${foo_dll_path}"
IMPORTED_IMPLIB "${foo_lib_path}"
)
target_link_libraries(my_project PUBLIC foo)
Later on a post build event is triggered to create hard links to all dependent 3rd party libraries via $<TARGET_RUNTIME_DLLS:my_project>
generator expression.
How can bar.dll
be introduced in this setup to be visible in $<TARGET_RUNTIME_DLLS:my_project>
?
So far I tried to add bar.dll
as yet another imported target via add_library(bar UNKNOWN IMPORTED)
and add_library(bar SHARED IMPORTED)
and setting IMPORTED_LOCATION
on bar
accordingly, which however does create linker errors.
Example:
add_library(bar UNKNOWN IMPORTED)
set_target_properties(bar PROPERTIES
IMPORTED_LOCATION "${bar_dll_path}"
)
target_link_libraries(foo INTERFACE bar)
In case of UNKNOWN
the linker will use bar.dll
as linker input, which of course fails, in case of SHARED IMPORTED
CMake demands that IMPORTED_IMPLIB
is set, but neither do I have the import library for bar.dll
nor do I want to link my_project
against it.
Any other suggestions how to deal with this?
Solution 1:[1]
Since there seems to be no proper solution to this issue I came up with a (possibly fragile) workaround involving a meta target:
# same as before
add_library(foo_real SHARED IMPORTED)
set_target_properties(foo_real PROPERTIES
IMPORTED_LOCATION "${foo_dll_path}"
IMPORTED_IMPLIB "${foo_lib_path}"
)
# add SHARED IMPORTED target with the importlib pointing to foo_reals importlib location
add_library(bar SHARED IMPORTED)
set_target_properties(bar PROPERTIES
IMPORTED_LOCATION "${bar_dll_path}"
IMPORTED_IMPLIB "${foo_lib_path}" # same lib path as for imported target foo
)
# add meta target to combine both
add_library(foo INTERFACE IMPORTED)
target_link_libraries(foo INTERFACE foo_real bar)
# finally link the meta target to the final project
target_link_libraries(my_project PUBLIC foo)
This workaround will cause CMake to generate a build script passing foo.lib
multiple times to the linker which does not seem to cause problems with the current MSVC Toolset. Also bar.dll
will now be part of TARGET_RUNTIME_DLLS
as intended.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Quxflux |