cmake - 如何从包含项目的源代码树中包含 CMake 文件
问题描述
我正在为一个用 C 编写的旧框架建立一个基于 CMake 的构建系统。它由一个二进制文件、一些核心库和许多动态链接库组成,这些库是针对核心库构建的。我的目标是在几个 CMake 项目(“基础框架”、“扩展库”……)中构建这些库,支持两种场景:
针对基础框架的构建树独立构建扩展库:
- base_framework/ - cmake/ - functions.cmake - core_libraries/ - CMakeLists.txt - extension_libs/ - lib1/ - lib2/ - CMakeLists.txt
对于这种情况,我使用
export(EXPORT foo FILE FooFrameworkConfig.cmake)
和
find_package(FooFramework)
CMAKE_PREFIX_PATH
并在配置extension_libs
项目时添加构建树。使用基础框架和扩展库作为应用程序特定项目的子项目(例如,作为 git 子模块):
- my_project/ - base_framework/ - cmake/ - functions.cmake - core_libraries/ - CMakeLists.txt - extension_libs/ - lib1/ - lib2/ - CMakeLists.txt - my_lib1/ - CMakeLists.txt
对于这种情况,我
add_subdirectory()
同时使用基本框架和扩展库。
(第三种情况是针对基本框架的安装树构建扩展库。不幸的是,这种情况目前被其他 CMake 问题所阻止。)
现在,我想将包含base_framework/cmake/functions.cmake
所有库的一些自定义 CMake 函数的文件包含到这两种情况下的所有项目的顶级CMakeLists.txt
s 中。
对于第二种情况,我只需在以下位置设置一个缓存的 CMake 变量base_framework/CMakeLists.txt
:
set(BASE_FRAMEWORK_DIR ${CMAKE_CURRENT_SOURCE_DIR}
CACHE PATH "" FORCE)
并使用此变量来包含函数文件extension_libraries/CMakeLists.txt
以及my_project/CMakeLists.txt
:
include(${BASE_FRAMEWORK_DIR}/cmake/functions.cmake)
但是如何在第一个场景中找到function.cmake
基础框架的源代码树中的文件?extenstion_libs/cmake
所有目录(base_framework
, extension_libs
,基本框架的构建树)可能位于我计算机上的任何位置。
解决方案
为了扩展我对您的第一个场景的评论,您似乎可以设置导出core_libraries
目标的一个属性以包含base_framework/cmake
模块的路径。所以你可以在base_framework/CMakeLists.txt
文件中设置这个,让我们在LABELS
目标属性中设置它。然后,我们告诉 CMake 使用以下命令导出LABELS
属性EXPORT_PROPERTIES
:
你的base_framework/CMakeLists.txt
文件:
# Define the path to 'base_framework/cmake'
set(BASE_FRAMEWORK_CMAKE_MODULES "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
add_library(CoreLibrary1 ...)
# Set the LABELS property, and tell CMake to export it.
set_target_properties(CoreLibrary1 PROPERTIES
LABELS "${BASE_FRAMEWORK_CMAKE_MODULES}"
EXPORT_PROPERTIES "LABELS"
)
# Define the export 'foo'.
install(TARGETS CoreLibrary1 EXPORT foo DESTINATION /path/to/install/targets)
export(EXPORT foo FILE FooFrameworkConfig.cmake)
这将确保base_framework
CMake 模块的路径被显式导出,并且可以在被另一个项目导入时访问:
你的extension_libs/CMakeLists.txt
文件:
find_package(FooFramework)
# Get the LABELS property from the imported target.
get_target_property(BASE_FRAMEWORK_MODULE_DIR CoreLibrary1 LABELS)
message(STATUS "BASE_FRAMEWORK_MODULE_DIR: ${BASE_FRAMEWORK_MODULE_DIR}")
通过调试message()
,我们可以验证 CMake 模块目录是否已导入:
BASE_FRAMEWORK_MODULE_DIR: /your/path/to/base_framework/cmake
编辑LABELS
:您还可以使用define_property()
为目标定义自己的自定义属性,而不是劫持目标属性。
推荐阅读
- xamarin - 将日期时间插入 SQLite 数据库 Xamarin.Forms
- sorting - 在 O(n log log n) 中对 log (n) 排序的子序列进行排序
- c# - CheckBoxList – 成功,RadioButtonList – 失败
- google-sheets - 根据另一个单元格的值更改单元格的颜色
- powermockito - PowerMokito 1.7.4 @Spy 注释不起作用
- c - C中带有指针和结构数组的结构
- scala - 工件 ID 中包含的 Scala 和 Scala.js 版本
- mysql - 使用修剪功能缩小结果集
- database - Neo4j 节点属性数组来创建关系
- api - 当我将 Swagger API 导入 Postman 时,所有请求名称在 Postman GUI 中最终都是空白的