Consider a library frob
that can be built as shared and static library in one go. That's usually achieved with two libraries that only differ in STATIC
/ SHARED
(c.f. setup details below). For convenience we add a third interface library (automatic
) solely for selecting the right library version depending on BUILD_SHARED_LIBS
.
That works very well when building the project itself. But the library should also be consumable from an install. In that case, the auto-detection for automatic
does not work any more. This is due to the fact that the criterion is evaluated in the installed project, rather than the consuming one (Frob::automatic
has a fixed dependency on either static
or shared
in the installed FrobConfig.cmake
).
Question: How to install Frob::automatic
s.t. it depends on either Frob::static
or Frob::shared
depending on BUILD_SHARED_LIBS
(of a consuming project)? In other words, how to install a dynamic dependency (e.g. depending on BUILD_SHARED_LIBS
)?
Setup for Frob
Let's start with the very basic library setup for frob
:
project(frob CXX)
# User configuration
option(FROB_BUILD_STATIC "Build statically linked library version." ON)
option(FROB_BUILD_SHARED "Build shared, dynamically linked library version." ON)
if (FROB_BUILD_STATIC)
add_library(frob-static STATIC ...)
set_target_properties(frob-static PROPERTIES EXPORT_NAME static)
add_library(Frob::static ALIAS frob-static)
endif()
if (FROB_BUILD_SHARED)
add_library(frob-shared SHARED ...)
set_target_properties(frob-shared PROPERTIES EXPORT_NAME shared)
add_library(Frob::shared ALIAS frob-shared)
endif()
# For convenience, we provide an interface library to automagically select the right version
# (depending on build setup and `BUILD_SHARED_LIBS`)
add_library(frob-automatic INTERFACE)
if (FROB_BUILD_SHARED AND (BUILD_SHARED_LIBS OR NOT FROB_BUILD_STATIC))
target_link_libraries(frob-automatic INTERFACE frob-shared)
else ()
target_link_libraries(frob-automatic INTERFACE frob-static)
endif ()
add_library(Frob::automatic ALIAS frob-automatic)
set_target_properties(frob-automatic PROPERTIES EXPORT_NAME automatic)
# Furthermore `frob` should be installable:
if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
include(GNUInstallDirs)
# [...] meta data
install(
TARGETS frob-shared frob-static frob-automatic
EXPORT frob
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
install(
EXPORT frob
FILE FrobConfig.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Frob
NAMESPACE Frob::
)
include(CPack)
endif()
Setup of a consumer
Consider the consuming project consume
project(consume CXX)
set(BUILD_SHARED_LIBS OFF)
add_executable(auto Automatic.cpp)
target_link_libraries(auto Frob::automatic)
The above question is how to install frob
s.t. the configuration of BUILD_SHARED_LIBS
in the consume
-ing project controls whether auto
is linked against Frob::static
or Frob::shared
.