CMake 嵌套库

J.P*_*ini 2 c++ cmake

我有一个 C++ 项目,其中 myexecutable依赖于 my core library,并且该库依赖于另一个外部库(libtorrent如果有任何相关性)。

问题是我不知道如何设置我的 CMakeLists.txt,我已经搜索了好几天,但无济于事。

主要思想是 和core library位于executable单独的 git 存储库中,因此该库不是可执行文件的子 git 模块。

最好我能够使用ExternalProject_Add将其添加core library到,executable但是当我这样做时,它executable抱怨它不知道libtorrent核心库再次使用哪个。将 的标头添加libtorrent到可执行文件还不够,我还需要将 链接executablelibtorrent. 但为什么我要编译core librarythen 呢,因为我只需将 the 的所有依赖项添加core libraryexecutableAgain 中。

如果有人可以为我指明如何设置一个使用具有其他依赖项的核心库和使用该核心库的可执行文件的项目的正确方向。

Gui*_*cot 5

通常,这用目标和它们之间的链接来表示。

您的设置可能如下所示:

#  core cmake file
find_package(LibtorrentRasterbar REQUIRED)

add_library(core_lib file1.cpp file2.cpp file3.cpp ...)
target_link_libraries(core_lib PUBLIC LibtorrentRasterbar::torrent-rasterbar) # see below
Run Code Online (Sandbox Code Playgroud)
# app cmake file

find_package(core_lib) # find it elsewhere

add_executable(app file1.cpp file2.cpp file3.cpp ...)
target_link_libraries(exec PRIVATE core_lib::core_lib)
Run Code Online (Sandbox Code Playgroud)

如果 core 的标头中需要新的库,那么您应该将它们添加到core_lib. 任何公共需求都会传递给用户,例如app目标。

与外部库或构建树的依赖关系使用 表示find_library。它可以是安装在根目录中的库,安装在用户目录中的库,安装在项目子目录中的库,或者只是库的构建树。就您而言,找到构建树可能就是您想要的。

然后,由于您的core_lib库位于另一个项目中,我建议您看看如何从构建树或安装中导出目标,这样find_package(core_lib)就可以了。


不幸的是,它似乎无法正确支持 CMake,因此无法找到Libtorrent包并且无法定义目标。LibtorrentLibtorrent::torrent-rasterbar

有一些方法可以通过尝试他们的来解决FindLibtorrentRasterbar.cmake

看看他们的 find 模块,很明显它不是用现代 cmake 制作的。如果文件支持链接到其目标,则必须在末尾添加这些行:

if(LibtorrentRasterbar_FOUND)
    set(LibtorrentRasterbar_LIBRARY_DEPS "${LibtorrentRasterbar_LIBRARIES}")
    list(REMOVE_ITEM LibtorrentRasterbar_LIBRARY_DEPS ${LibtorrentRasterbar_LIBRARY})

    if(LibtorrentRasterbar_USE_STATIC_LIBS)
        add_library(LibtorrentRasterbar::torrent-rasterbar STATIC IMPORTED GLOBAL)
    else()
        add_library(LibtorrentRasterbar::torrent-rasterbar SHARED IMPORTED GLOBAL)
    endif()

    set_target_properties(LibtorrentRasterbar::torrent-rasterbar PROPERTIES
        IMPORTED_LOCATION ${LibtorrentRasterbar_LIBRARY}
        INTERFACE_LINK_LIBRARIES ${LibtorrentRasterbar_LIBRARY_DEPS}
        INTERFACE_COMPILE_DEFINITIONS ${LibtorrentRasterbar_DEFINITIONS}
        INTERFACE_INCLUDE_DIRECTORIES ${LibtorrentRasterbar_INCLUDE_DIRS}
    )
endif()
Run Code Online (Sandbox Code Playgroud)

我没有提到的一个细节是,它find_package不会尝试查找您的依赖项的包。为此,请创建一个如下所示的自定义配置文件:

# cmake/core_lib-config.cmake.in
include(CMakeFindDependencyMacro)

# this line is just like a find_package
# but made for transitivity
find_dependency(LibtorrentRasterbar)
include("${CMAKE_CURRENT_LIST_DIR}/core_lib-targets.cmake")
Run Code Online (Sandbox Code Playgroud)

然后将导出更改为输出core_lib-targets.cmake而不是通常的配置:

# this is the new config file with the add_dependency
configure_file(
    cmake/core_lib-config.cmake.in
    core_lib-config.cmake
    @ONLY
)

# the new config file will include this target file
install(EXPORT core_lib_targets
        NAMESPACE core_lib::
        FILE core_lib-targets.cmake
        DESTINATION lib/cmake/core_lib)

# export the current build tree
export(
    EXPORT core_lib_targets
    NAMESPACE core_lib::
    FILE "${CMAKE_CURRENT_BINARY_DIR}/core_lib-targets.cmake"
)
Run Code Online (Sandbox Code Playgroud)