cmake - CMake:如何构建通过 add_subdirectory() 为 find_package() 导出的多个项目
问题描述
我有一个导出的库项目,因此消费者可以像这样使用它:
find_package(myLibrary)
target_link_libraries(theirLibrary PUBLIC myNamespace::myLibrary)
MyLibrary 是主要产品,但它与我们存储库中的其他两个项目一起存在,布局如下所示:
MyRepository/
MyLibrary/
CMakeLists.txt
include/ //public headers
MyLibrary/ //sources and private headers
MyDependentLibrary/ //another library project
CMakeLists.txt
etc..
MyExample //executable project
CMakeLists.txt
etc..
每个项目的依赖关系如下:
MyLibrary: None
MyDependentLibrary: MyLibrary
MyExample: MyLibrary, MyDependentLibrary
MyLibrary 和 MyDependentLibrary 都设置了安装和构建目录导出以与 find_package() 命令兼容。所以要构建你的一切:
- 配置/构建 MyLibrary
- 提示时配置 MyDependantLibrary 设置
MyLibrary_DIR
,然后构建它 - 配置 MyExample 设置
MyLibrary_DIR
,并MyDependentLibrary_DIR
在出现提示时构建它
这个工作流程很棒,大多数时候我们只想在发送给客户时打包 MyLibrary 而没有其他项目,但偶尔我们想给他们所有 3 个项目的源代码,以便他们有更多示例可供查看。
出于这个原因,我很想添加一个顶级CMakeLists.txt
文件,我认为它看起来像这样:
cmake_minimum_required(VERSION 3.10 FATAL_ERROR)
project(MyCombinedProject VERSION 1.0.0 LANGUAGES CXX)
add_subdirectory(MyLibrary)
add_subdirectory(MyDependentLibrary)
add_subdirectory(MyExample)
但是,这不起作用。配置“组合”项目时,MyDependentLibrary 无法找到MyLibrary_DIR
,这是有道理的,因为尚未构建 MyLibrary。
除了 find_package() 之外,有没有办法向每个库添加导出,以便在以这种方式添加时可以找到它们?我真的不想将构建 MyLibrary 所需的任何 CMake 代码移动到顶层CMakeLists.txt
,因为 90% 的时间它将自行交付。
解决方案
您可以使用伪配置文件发送库 (MyLibrary) 的源代码,该文件仅提供myNamespace::myLibrary
target 作为myLibrary
.
我的图书馆/CMakeLists.txt:
# Assuming you create a library
add_library(mylibrary ...)
# Install and export it
install(TARGETS mylibrary EXPORT mylibraryTargets ...)
# and install the file which describes this installation
install(EXPORT mylibraryTargets NAMESPACE myNamespace ...)
# Then you install config file for your library:
install(FILES myLibrary.cmake ...)
# Then just set `MyLibrary_DIR` variable to point into in-source version of config file.
set(MyLibrary_DIR CACHE INTERNAL "A directory with the in-source config file"
${CMAKE_CURRENT_SOURCE_DIR}/cmake
)
并按如下方式编写该源配置文件:
MyLibrary/cmake/MyLibraryConfig.cmake:
add_library(myNamespace::mylibrary ALIAS mylibrary)
这样,find_package(MyLibrary)
如果在配置库的源 ( ) 之后发布它,它将起作用add_subdirectory(MyLibrary)
。
推荐阅读
- xml - 在 ST 转换中连接值?
- java - 内存参考
- ios - 是否可以在不运行完整构建的情况下测试配置文件是否有效?
- python - 如何在高屏幕的左上角和右上半部分设置框架?
- outlook-addin - Outlook 插件:清单 XML 中的“ExtendedPermissions”以使用“AppendOnSend”函数(Office.Body.appendOnSendAsync API)
- java - mergeSort 简单的输出不合适
- android-studio - Android从drawable目录动态加载gif
- elasticsearch - 用于 APM UI 的 Elastisearch 查询速度很慢
- datatables - 数据表、fixedHeader 和 header 列点击
- elasticsearch - 清理 ElasticSearch 参数?