链接两个独立的 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.
我有两个独立的项目,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.