Conditional transitive link libraries
I'm struggling with a CMake-based "Config" package description when using two dependent packages where the upstream package has additional link libraries.
Suppose you have libA
one that optionally uses zip functionality (say with some option USE_ZLIB
in libA
CMakeLists.txt
). This means it libA
does not necessarily have -lz
in its INTERFACE_LINK_LIBRARIES
(exported to liba-config.cmake
). Now, if you have libB
using libA
via find_package(libA)
, how do you know if it was built libA
with or without zlib support when both libraries are installed and exported using the CMake package configuration system?
I know the link library information is processed in transit and will propagate to the link libraries libB
, so it -lz
will be displayed whenever it is linked to libB
. However, PATH
to libz is not included anywhere; hence the link fails with "cannot find library z" unless you know what libz
the link library is libA
and where to include it. Inclusion of an absolute path in the libz
in the libA
config is also not suitable, because it destroys the portability on different systems.
Edit: I am getting answers suggesting to use target_link_libraries(libA PRIVATE z)
eg. declaring (actually internal libA) libz as a private library. Unfortunately, this does not solve the problem, as CMake automatically adds any A- PRIVATE
labeled link library to the list INTERFACE_LINK_LIBRARIES
via $<LINK_ONLY:z>
. This shows the need for -lz
the list of exported libraries to have links in another way (and that the authors of the CMake export script understand the transitive problem).
source to share
The canonical way to do this is to make a template liba-config.cmake
and configure_file () to fill it with information about build capabilities.
For example, yours CMakeLists.txt
looks like this:
if(ZLIB_FOUND)
... # link with ZLIB
set(BUILT_WITH_ZLIB 1)
endif()
... # more options
configure_file(alib-config.cmake.in alib-config.cmake)
liba-config.cmake.in
Should now have
set(BUILT_WITH_ZLIB @BUILT_WITH_ZLIB@)
if(BUILT_WTH_ZLIB)
# append lz to ALIB_LIBRARIES or whetever you variable is called
endif()
After configuration alib-config.cmake
will contain set(BUILT_WITH_ZLIB 0)
or set(BUILT_WITH_ZLIB 1)
depending on its value in CMake.
source to share