是否可以将 cmake 项目链接到子项目?

Posted

技术标签:

【中文标题】是否可以将 cmake 项目链接到子项目?【英文标题】:Is it possible to link a cmake project to subprojects? 【发布时间】:2016-06-09 07:10:01 【问题描述】:

我有一个带有 examples 文件夹的 C++ 库项目。这些示例是独立的,即它们可以在没有源代码树的其余部分的情况下进行编译,就好像它们是使用该库的真实应用程序一样。他们使用提供的FindMyLib.cmake 在系统中查找已安装的库。

我希望能够将它们与整个库一起构建。最初,我将它们添加为子目录:

if(MYLIB_BUILD_EXAMPLES)
    add_subdirectory(examples/fooexample)
    add_subdirectory(examples/barexample)
endif()

但这行不通,因为在安装库之前我不能使用find_package。我可以将默认构建目录添加到搜索路径,但这还不够,因为在 cmake 运行时(显然)还没有构建库。

我能做些什么来解决这个问题?有没有办法在构建库时透明地将库链接到这些子项目(并且还“禁用”find_package,因为如果没有安装它肯定会失败)。

【问题讨论】:

【参考方案1】:

只需准备 fake FindMyLib.cmake,它使用 build 树链接到库,而不是 install 树。例如,它可以将变量MyLib_LIBRARY 变量设置为库目标

cmake-build/FindMyLib.cmake

set(MyLib_LIBRARY MyLib)
set(MyLib_INCLUDE_DIRECTORIES $CMAKE_SOURCE_DIR/include)
...

然后在CMAKE_MODULE_PATH 列表前面加上目录,包含假脚本。这样的方式将被示例使用:

if(MYLIB_BUILD_EXAMPLES)
    set(CMAKE_MODULE_PATH $CMAKE_SOURCE_DIR/cmake-build $CMAKE_MODULE_PATH)
    add_subdirectory(examples/fooexample)
    add_subdirectory(examples/barexample)
endif()

【讨论】:

除非我遗漏了什么,否则这是行不通的:示例的配置步骤将导致错误,因为该库尚未构建, 如果添加库(使用add_library(MyLib)之前 add_subdirectory(examples/...),则target_link_libraries(fooexample $MyLib_LIBRARY)target 的链接正常工作。此阶段不需要构建库目标。 谢谢,抱歉这么晚才回来。我真的很喜欢这个解决方案,因为它具有额外的好处,即能够为没有用于树内构建的条件逻辑的示例提供 CMakeLists.txt。【参考方案2】:

在您的示例中,一个解决方案可能是检查构建MyLib 的目标是否存在,如果存在,则将其用作依赖项;否则调用find_library()

add_library(MyLib ...)

# examples/fooexample
if(NOT TARGET MyLib)
  find_library(MyLib)
endif()

add_executable(foo)

if(TARGET MyLib)
  add_dependencies(foo MyLib)
endif()

【讨论】:

以上是关于是否可以将 cmake 项目链接到子项目?的主要内容,如果未能解决你的问题,请参考以下文章

CMake:将第三方库链接到项目库

注册。使用 CMake 将外部库链接到项目

Cmake:将子目录链接模式覆盖为 LINK_PRIVATE

如何将 TensorFlow Lite 构建为静态库并从单独的(CMake)项目链接到它?

CMake 访问 SWIG 并将 java 库链接到现有 C++ 项目的问题

CMake:具有多个项目的静态库