如何安装 cmake-project 的动态依赖项?

时间:2021-04-25 14:02:50

标签: cmake

考虑一个可以一次性构建为共享和静态库的库 frob。这是 usually 通过两个仅在 STATIC / SHARED 上不同的库实现的(参见下面的设置详细信息)。为方便起见,我们添加了第三个接口库 (automatic),专门用于根据 BUILD_SHARED_LIBS 选择正确的库版本。

这在构建项目本身时非常有效。但是该库也应该可以从安装中使用。在这种情况下,automatic 的自动检测不再起作用。这是因为标准是在已安装的项目中评估的,而不是在使用的项目中(Frob::automatic 对已安装的 static 中的 sharedFrobConfig.cmake 具有固定的依赖性}}).

问题:如何安装 Frob::automatic s.t.它取决于 Frob::staticFrob::shared 取决于 BUILD_SHARED_LIBS(消费项目)?换句话说,如何安装动态依赖(例如依赖于 BUILD_SHARED_LIBS)?


Frob 的设置

让我们从 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()

消费者的设置

考虑消费项目 consume

project(consume CXX)

set(BUILD_SHARED_LIBS OFF)

add_executable(auto Automatic.cpp)
target_link_libraries(auto Frob::automatic)

上面的问题是如何安装frob s.t. BUILD_SHARED_LIBS-ing 项目中 consume 的配置控制 auto 是链接到 Frob::static 还是 Frob::shared

1 个答案:

答案 0 :(得分:0)

诀窍是不安装 automatic,而是通过额外的间接层提供它。以下是 frob 的更新项目详情:

# [...] as above

if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
    include(GNUInstallDirs)
    # [...] meta data
    install(
        TARGETS frob-shared frob-static # no frob-automatic any more
        EXPORT frob
        INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
    )
    install(
        EXPORT frob
        FILE FrobConfigGenerated.cmake # new Generated suffix
        DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Frob
        NAMESPACE Frob::
    )
    # Here's the new layer of indirection.
    install(
        FILES FrobConfig.cmake
        DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Frob
    )
    include(CPack)
endif()

新的 FrobConfig.cmake 包含的位置

# Import central (generated) configuration details.
get_filename_component(_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
include(${_DIR}/FrobConfigGenerated.cmake)

# Introduce automatic aliases
if (BUILD_SHARED_LIBS)
    add_library(Frob::automatic ALIAS Frob::shared)
else ()
    add_library(Frob::automatic ALIAS Frob::static)
endif ()

当消费项目(即在 find_package(Frob) 之后)链接到 Frob::automatic 时,根据 Frob::shared 引用 Frob::static / BUILD_SHARED_LIBS

fabiancomment非常感谢。