链接两个独立的 cmake 项目,其中一个项目依赖于另一个项目

Linking two separate cmake projects where one is dependant on the other

我有两个独立的项目,A 和 B。它们都有大型文件夹结构,很多依赖项,并且都有自己的 CMakelists.txt 结构。彼此都不依赖。 我正在向项目 A 添加新功能,该功能依赖于项目 B 中的 header,以及项目 B 中 header 所依赖的文件网络。 我不知道用 cmake link 这些的正确方法。我添加到 header 作为代码中必要的包含,但我不确定 link 的正确方法。我是否使用 target_include_directories 并添加来自项目 B 或源代码或两者的二进制文件?项目 A 不会构建 B,因为它已经设置好,二进制文件和源代码位于单独的子目录中。我只需要 A 就可以调用 B 的功能。 我对 cmake 还不是很熟悉,所以任何指针将不胜感激。 谢谢。

如果您只想使用 headers 而不是 object 文件,那么只需 target_include_directories 即可。依赖跟踪将由 cmake 和 ninja/make 自动完成。

或者,如果您需要同时包含 B 中的 headers 和 object,您确实希望将这些位分解到 B 中的小型 stand-alone 静态库中,然后 link 与来自 A 的那些库 - 这将添加包含文件路径和所有其他需要的东西。 cmake 非常擅长。

项目 B 应该导出其目标。

这样,在项目 A 中,您可以这样做:

find_package(B REQUIRED)
target_link_libraries(A PUBLIC B::B)

并且在调用CMake时,在前缀路径中添加B的构建目录:

# in A/build
cmake .. -DCMAKE_PREFIX_PATH=/path/to/B/build

但是为了让它起作用,您必须更改 B CMake 文件以导出您的目标(应该如此):

include(GNUInstallDirs)

add_library(B INTERFACE)
add_library(B::B ALIAS B)

target_link_libraries(B PUBLIC dependency-of-B)
target_compile_features(B INTERFACE cxx_std_17) # or any language version

# Set B include directory. Will add include directory for both B and A
target_include_directories(B PUBLIC
    $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}>
    $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/your-include-dir>
)

file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/cmake/B-config.cmake" DESTINATION ${CMAKE_CURRENT_BINARY_DIR})
install(TARGETS B EXPORT B-targets)
# install package
install(EXPORT B-targets
    FILE B-targets.cmake
    NAMESPACE B::
    DESTINATION share/cmake/B
)
# export build tree
export(
    EXPORT B-targets
    FILE "${CMAKE_CURRENT_BINARY_DIR}/B-targets.cmake"
    NAMESPACE B::
)

B-config.cmake:

include(CMakeFindDependencyMacro)

# All find_package we used in CMakeLists.txt should also be there
find_dependency(dependency1 REQUIRED)
find_dependency(dependency2 REQUIRED)

include("${CMAKE_CURRENT_LIST_DIR}/B-targets.cmake")

如果你在B中有很多目标,你应该install(TARGETS other-target EXPORT B-targets)

我强烈建议您查看导出其目标的库示例,以便您可以以此为基础进行工作。例如,glm 库导出其目标并且始终运行良好。我还添加了 target exportation in msdfgen project.