首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >cmake:如何引用和构建单独的cmake项目依赖?

cmake:如何引用和构建单独的cmake项目依赖?
EN

Stack Overflow用户
提问于 2018-02-01 13:00:22
回答 2查看 4.4K关注 0票数 7

我有一个交叉编译器的cmake项目,它依赖于来自另一个项目的库,该项目碰巧也使用cmake:

代码语言:javascript
复制
/myProject/CMakeLists.txt (uses cross-compiler)
/anotherProject/CMakeLists.txt (platform-agnostic)

anotherProject可以完全独立构建。它对myProject一无所知。

现在,anotherProject有很多我需要的模块,比如:

代码语言:javascript
复制
anotherProject/A/CMakeLists.txt (produces static lib A.a)
anotherProject/B/CMakeLists.txt (produces static lib B.a)
etc

在生成myProject时,我希望生成并链接到另一个项目/A和另一个项目/B,以生成共享库myproject.so。如果可能的话,我想利用anotherProject的现有特性,而不是手动从myProject中删除它的各种源码集。

使用cmake实现这一点的正确方法是什么?我觉得我漏掉了一些明显的东西。

比方说,如果myProject只是anotherProject下的一个子目录,或者如果有一个可以同时引用myProject和anotherProject的顶级CMakeLists.txt,这将是很简单的;但这都不是我想要的。我知道我可以构建anotherProject并将其库导出到一个众所周知的位置,然后从myProject引用导出目录-但我也希望避免这种设置。

EN

回答 2

Stack Overflow用户

发布于 2018-02-01 17:20:54

一种解决方案是使用CMake packages

基本上,在anotherProject中,您可以手工创建一个CMake配置文件,在其中设置myProject使用的变量(例如,包括目录、库列表、编译标志...),甚至目标。

然后,在myProject中,使用find_package()机制,以便CMake找到此配置文件并导入当前项目中的变量/目标。

在CMake维基上有一个tutorial

票数 2
EN

Stack Overflow用户

发布于 2018-02-01 17:38:00

根据您的需求,我能想到的唯一替代设置是允许您的主(依赖)项目使用find_package发现其他(依赖)项目。

在您的主项目CMakeLists.txt中,您应该添加如下内容:

代码语言:javascript
复制
find_package(anotherProject CONFIG)

if(anotherProject_FOUND)
  message(STATUS "Found project dependency: anotherProject")
else
  # change WARNING to FATAL_ERROR if the dependency is NOT optional
  message(WARNING "package anotherProject was not found")
endif()

有关CONFIGMODULE模式之间的区别,请查看文档和此link

然后假设您的主项目创建了一个可执行文件,您可以像这样将发现的依赖项连接起来:

代码语言:javascript
复制
add_executable(myProject ${SOURCES})
[...]

if(anotherProject_FOUND)
   target_link_libraries(myProject PUBLIC anotherProject)
endif()

这也应该考虑到所需的包含文件和定义。

现在,在依赖项目CMakeLists.txt中,您应该这样做:

代码语言:javascript
复制
set(PRJ_NAME "anotherProject")
string(TOLOWER ${PRJ_NAME} PRJ_NAME_LOWER)
set(ANOTHERPROJECT_EXPORT_NAME "${PRJ_NAME}")

install(TARGETS ${PRJ_NAME} EXPORT ${ANOTHERPROJECT_EXPORT_NAME}
  RUNTIME DESTINATION .)
install(EXPORT ${ANOTHERPROJECT_EXPORT_NAME} DESTINATION "share/cmake")

这会将导出与目标相关联,然后安装导出。

现在,如果你检查导出文件,它希望找到某些东西和included,这可能是特定于你的项目的。要使其尽可能灵活,您可以使用configure特性从模板生成它们,然后从install目录生成它们。

因此,在项目中名为share/cmake的子目录下,您可以拥有一个名为config.cmake.in的文件,其中包含以下内容:

代码语言:javascript
复制
include(${CMAKE_CURRENT_LIST_DIR}/@PRJ_NAME@.cmake)

在主项目的CMakeLists.txt中,您需要添加以下内容,以便从该模板生成文件:

代码语言:javascript
复制
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/share/cmake/config.cmake
  ${CMAKE_CURRENT_BINARY_DIR}/share/cmake/${PRJ_NAME_LOWER}-config.cmake)

install(DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/share/
  DESTINATION share)

注意,我使用了PRJ_NAME,因为您可以在add_executable命令中重用它来命名实际的可执行文件。如果导出的目标与生成的目标具有相同的名称,则在心理上会有所帮助。

这是一个更通用的版本,可以容纳this教程的多个子项目。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48555648

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档