我正在为一个用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
文件包含到所有项目的顶级CMakeLists.txt
中,该文件包含所有库的一些自定义CMake函数。
对于第二种情况,我只是在base_framework/CMakeLists.txt
中设置了一个缓存的CMake变量:
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
,基础框架的构建树)可能在我的计算机上的任何位置。
答案 0 :(得分:0)
要进一步说明我对第一种情况的评论,您似乎可以将导出的core_libraries
目标的一个属性设置为包含base_framework/cmake
模块的路径。因此,您可以在base_framework/CMakeLists.txt
文件中进行设置,让我们在LABELS
target属性中进行设置。然后,我们告诉CMake使用EXPORT_PROPERTIES
导出LABELS
属性:
您的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()
为目标定义自己的自定义属性。