CMake指令:set_property和get_property
目录
1.简介
1.1.set_property 命令
1.2.get_property 命令
2.全局属性(Global Properties)
2.1.set_property 设置全局属性
2.2.get_property 获取全局属性
2.3.典型应用场景
3. 目录属性(Directory Properties)
3.1.set_property 设置目录属性
3.2.get_property 设置目录属性
3.3.典型应用场景
4.目标属性(Target Properties)
4.1.set_property 设置目标属性
4.2.get_property 设置目标属性
4.3.典型应用场景
4.4.与高层级命令的对比与选择
5.源文件属性(Source File Properties)
5.1.set_property 设置源文件属性
5.2.get_property 设置源文件属性
5.3.典型应用场景
5.4.与其他作用域的对比
6.缓存变量属性(Cache Variable Properties)
6.1.set_property 设置缓存变量属性
6.2.get_property 获取缓存变量属性
6.3.典型应用场景
6.4.与普通变量的对比
7.注意事项
8.典型应用场景整合示例
9.总结
相关链接
1.简介
在 CMake 中,set_property
和 get_property
是用于操作目标(target)、目录(directory)、文件(file)等实体属性的核心命令,支持细粒度的属性控制。
1.1.set_property
命令
set_property(<GLOBAL | DIRECTORY | TARGET | SOURCE | TEST> # 作用域PROPERTY <属性名> <属性值>[APPEND | APPEND_STRING] # 追加模式(可选)
)
-
作用域说明
作用域 | 影响范围 | 典型应用场景 |
---|---|---|
GLOBAL | 整个项目(所有后续模块可见) | 跨模块共享版本号、全局编译开关 |
DIRECTORY | 当前目录及子目录(默认作用域) | 目录级编译选项、包含目录配置 |
TARGET | 特定目标(可执行文件、库) | 目标的编译选项、链接库、版本信息 |
SOURCE | 单个源文件(如 .cpp 、.h ) | 源文件级宏定义、编译选项(如禁用特定警告) |
TEST | 测试用例(通过 add_test 创建) | 测试的运行环境、额外参数配置 |
CACHE | CMake 缓存变量 | 修改缓存属性(如 FORCE 强制重新配置) |
- 示例:
# 为目标设置编译选项(作用域:目标)
set_property(TARGET my_app PROPERTY COMPILE_OPTIONS "-Wall -Wextra")# 为目录添加自定义属性(作用域:目录)
set_property(DIRECTORY PROPERTY MY_CUSTOM_FLAG ON)# 追加属性值(避免覆盖)
set_property(TARGET my_lib PROPERTY INCLUDE_DIRECTORIES APPEND ${MY_INC_DIR})
- 常用属性举例
1.目标属性:COMPILE_OPTIONS
(编译选项)、LINK_LIBRARIES
(链接库)、OUTPUT_NAME
(输出文件名)。
2.源文件属性:COMPILE_DEFINITIONS
(预定义宏)、SKIP_AUTOMOC
(禁用 moc 工具)。
3.目录属性:CMAKE_CXX_STANDARD
(C++ 标准)、ADDITIONAL_MAKE_CLEAN_FILES
(清理文件)。
1.2.get_property
命令
get_property(<变量名><GLOBAL | DIRECTORY | TARGET | SOURCE | TEST> # 作用域PROPERTY <属性名>[SET] # 检查属性是否存在(可选)
)
-
返回值:
- 若属性存在,将值存入
<变量名>
;若不存在且未指定SET
,则变量为空。 - 若指定
SET
,则<变量名>
为1
(属性存在)或0
(不存在)。
- 若属性存在,将值存入
- 示例:
# 获取目标的包含目录
get_property(INC_DIRS TARGET my_lib PROPERTY INCLUDE_DIRECTORIES)
message(STATUS "my_lib include dirs: ${INC_DIRS}")# 检查目录是否设置了自定义属性
get_property(HAS_FLAG DIRECTORY PROPERTY MY_CUSTOM_FLAG SET)
if(HAS_FLAG)message(STATUS "Custom flag is enabled")
endif()
- 典型应用
1.动态判断第三方库是否存在(通过检查其属性)。
2.根据已有属性调整构建逻辑(如不同平台的编译选项)。
2.全局属性(Global Properties)
全局属性(Global Properties) 是一种特殊的属性类型,用于在整个项目范围内存储和共享数据。set_property
和 get_property
命令对全局属性的操作尤为重要,适用于跨模块通信、全局配置共享等场景。
核心特点:
- 作用域:全局属性在整个 CMake 项目中可见,所有子目录和后续包含的脚本都能访问。
- 存储方式:全局属性存储在 CMake 的全局状态中,不依赖于特定的目标或目录。
- 典型用途:
- 跨模块共享配置信息(如版本号、编译开关)。
- 收集项目中的文件列表或目标列表。
- 定义全局标志以控制构建流程。
2.1.set_property
设置全局属性
基本语法:
set_property(GLOBAL PROPERTY <PROPERTY_NAME> <VALUE> [APPEND])
示例 1:设置全局编译选项
set_property(GLOBAL PROPERTY COMPILE_OPTIONS "-Wall -Wextra")
示例 2:收集项目中的源文件(动态添加)
# 在顶层 CMakeLists.txt 中初始化
set_property(GLOBAL PROPERTY ALL_SOURCE_FILES "")# 在子目录中追加源文件
set_property(GLOBAL PROPERTY ALL_SOURCE_FILES APPEND ${CMAKE_CURRENT_SOURCE_DIR}/src/file1.cpp)
示例 3:定义全局开关
set_property(GLOBAL PROPERTY ENABLE_FEATURE_X ON)
2.2.get_property
获取全局属性
基本语法:
get_property(<VARIABLE> GLOBAL PROPERTY <PROPERTY_NAME> [SET])
示例 1:获取全局编译选项
get_property(global_options GLOBAL PROPERTY COMPILE_OPTIONS)
message(STATUS "全局编译选项: ${global_options}")
示例 2:检查全局开关状态
get_property(feature_x_enabled GLOBAL PROPERTY ENABLE_FEATURE_X SET)
if(feature_x_enabled)message(STATUS "功能 X 已启用")
endif()
示例 3:获取收集的源文件列表
get_property(all_sources GLOBAL PROPERTY ALL_SOURCE_FILES)
add_library(my_lib ${all_sources})
2.3.典型应用场景
1.跨模块版本同步
# 顶层 CMakeLists.txt
set_property(GLOBAL PROPERTY PROJECT_VERSION "2.3.0")# 子模块 CMakeLists.txt
get_property(VERSION GLOBAL PROPERTY PROJECT_VERSION)
set_property(TARGET my_lib PROPERTY VERSION ${VERSION})
2.全局编译选项控制
# 根据构建类型设置全局编译选项
if(CMAKE_BUILD_TYPE STREQUAL "Release")set_property(GLOBAL PROPERTY COMPILE_OPTIONS "-O3 -DNDEBUG")
else()set_property(GLOBAL PROPERTY COMPILE_OPTIONS "-g -O0")
endif()
3.插件系统管理
# 插件注册机制
set_property(GLOBAL PROPERTY REGISTERED_PLUGINS "")# 插件模块中注册
function(register_plugin plugin_name)set_property(GLOBAL PROPERTY REGISTERED_PLUGINS APPEND ${plugin_name})
endfunction()# 主程序中获取所有插件
get_property(plugins GLOBAL PROPERTY REGISTERED_PLUGINS)
message(STATUS "已注册插件: ${plugins}")
4.条件化构建流程
# 在顶层设置标志
option(USE_CUDA "启用 CUDA 支持" OFF)
if(USE_CUDA)set_property(GLOBAL PROPERTY ENABLE_CUDA ON)
endif()# 在子模块中查询标志
get_property(cuda_enabled GLOBAL PROPERTY ENABLE_CUDA SET)
if(cuda_enabled)# 添加 CUDA 相关配置find_package(CUDA REQUIRED)# ...
endif()
3. 目录属性(Directory Properties)
目录属性(Directory Properties) 用于控制特定目录及其子目录的构建行为。set_property
和 get_property
命令对目录属性的操作是模块化项目配置的关键,可实现编译选项、包含路径等的局部化管理。
核心特点:
- 作用域:目录属性影响当前目录及其所有子目录(递归生效)。
- 继承规则:子目录可继承父目录的属性,也可覆盖父目录的设置。
- 典型用途:
- 设置目录级编译选项(如 C++ 标准、警告级别)。
- 定义局部包含目录(避免全局污染)。
- 控制子目录的构建行为(如排除特定文件)。
3.1.set_property
设置目录属性
基本语法:
set_property(DIRECTORY [dir] PROPERTY <PROPERTY_NAME> <VALUE> [APPEND])
[dir]
:可选参数,指定目标目录(默认为当前目录)。
示例 1:设置目录级编译选项
# 为当前目录及子目录设置 C++ 标准
set_property(DIRECTORY PROPERTY CMAKE_CXX_STANDARD 20)# 为 src/ 目录添加额外编译选项
set_property(DIRECTORY src PROPERTY COMPILE_OPTIONS "-Werror")
示例 2:定义局部包含目录
# 仅在当前目录及子目录中添加 include/ 到搜索路径
set_property(DIRECTORY PROPERTY INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/include)
示例 3:控制子目录构建行为
# 排除某些文件不参与编译
set_property(DIRECTORY PROPERTY CMAKE_EXCLUDE_FROM_ALL ON)
3.2.get_property
设置目录属性
基本语法:
get_property(<VARIABLE> DIRECTORY [dir] PROPERTY <PROPERTY_NAME> [SET])
示例 1:获取当前目录的编译选项
get_property(current_options DIRECTORY PROPERTY COMPILE_OPTIONS)
message(STATUS "当前目录编译选项: ${current_options}")
示例 2:检查目录是否设置了特定属性
get_property(has_std DIRECTORY PROPERTY CMAKE_CXX_STANDARD SET)
if(has_std)get_property(cxx_std DIRECTORY PROPERTY CMAKE_CXX_STANDARD)message(STATUS "C++ 标准: ${cxx_std}")
endif()
示例 3:获取子目录的包含路径
get_property(sub_inc_dirs DIRECTORY src PROPERTY INCLUDE_DIRECTORIES)
message(STATUS "src/ 目录包含路径: ${sub_inc_dirs}")
3.3.典型应用场景
1. 编译选项控制
# 设置当前目录及子目录的编译选项
set_property(DIRECTORY PROPERTY COMPILE_OPTIONS "-Wall -Wextra -Wpedantic"
)# 为调试模式添加额外选项
if(CMAKE_BUILD_TYPE STREQUAL "Debug")set_property(DIRECTORY PROPERTY COMPILE_OPTIONS "${COMPILE_OPTIONS} -g -O0")
endif()
2.包含目录管理
# 为 modules/ 目录添加局部包含路径
set_property(DIRECTORY modules PROPERTY INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/modules/include
)# 在子目录中获取该属性
get_property(module_incs DIRECTORY modules PROPERTY INCLUDE_DIRECTORIES)
3.条件化构建
# 根据平台设置目录属性
if(WIN32)set_property(DIRECTORY src/win32 PROPERTY COMPILE_DEFINITIONS _WIN32)
elseif(UNIX)set_property(DIRECTORY src/unix PROPERTY COMPILE_DEFINITIONS _UNIX)
endif()
4.自定义目录标记
# 标记 tests/ 目录为测试目录
set_property(DIRECTORY tests PROPERTY IS_TEST_DIR ON)# 在顶层 CMakeLists.txt 中检查
get_property(is_test DIRECTORY tests PROPERTY IS_TEST_DIR SET)
if(is_test)enable_testing()add_subdirectory(tests)
endif()
4.目标属性(Target Properties)
目标属性(Target Properties) 是控制特定目标(如可执行文件、库)行为的核心机制。set_property
和 get_property
命令对目标属性的操作,允许开发者精确配置编译选项、链接行为、输出名称等关键参数。
核心特点:
- 作用域:仅影响特定目标(通过
add_executable
或add_library
创建)。 - 继承规则:不继承其他目标的属性,但可通过
PUBLIC
/INTERFACE
依赖传递。 - 典型用途:
- 设置目标的编译选项(如 C++ 标准、警告级别)。
- 控制链接行为(如链接库、链接选项)。
- 自定义输出文件名称、位置和版本信息。
4.1.set_property
设置目标属性
基本语法:
set_property(TARGET <target1> [<target2> ...] PROPERTY <PROPERTY_NAME> <VALUE> [APPEND])
示例 1:设置编译选项
add_executable(my_app src/main.cpp)
set_property(TARGET my_app PROPERTY COMPILE_OPTIONS "-Wall -Wextra")
示例 2:控制链接行为
add_library(my_lib SHARED src/lib.cpp)
set_property(TARGET my_lib PROPERTY LINK_LIBRARIES pthread m)
示例 3:自定义输出名称和版本
add_library(my_api SHARED src/api.cpp)
set_property(TARGET my_api PROPERTY OUTPUT_NAME "my-custom-api" # 自定义输出文件名VERSION "1.2.3" # 完整版本号SOVERSION "1" # 主版本号
)
4.2.get_property
设置目标属性
基本语法:
get_property(<VARIABLE> TARGET <target> PROPERTY <PROPERTY_NAME> [SET])
示例 1:获取目标的编译选项
get_property(options TARGET my_app PROPERTY COMPILE_OPTIONS)
message(STATUS "my_app 编译选项: ${options}")
示例 2:检查目标是否为 SHARED 库
get_property(is_shared TARGET my_lib PROPERTY TYPE)
if(is_shared STREQUAL "SHARED_LIBRARY")message(STATUS "my_lib 是共享库")
endif()
示例 3:获取目标的链接库
get_property(libs TARGET my_app PROPERTY LINK_LIBRARIES)
message(STATUS "my_app 链接库: ${libs}")
4.3.典型应用场景
1.编译选项控制
add_executable(my_app src/main.cpp)# 设置 C++ 标准
set_property(TARGET my_app PROPERTY CMAKE_CXX_STANDARD 20)# 为调试模式添加额外选项
if(CMAKE_BUILD_TYPE STREQUAL "Debug")set_property(TARGET my_app PROPERTY COMPILE_OPTIONS "-g -O0")
endif()
2.输出文件控制
add_library(my_lib STATIC src/lib.cpp)# 自定义输出文件名
set_property(TARGET my_lib PROPERTY OUTPUT_NAME "mylib")# 设置输出目录
set_property(TARGET my_lib PROPERTY ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib)
3.依赖传递控制
add_library(libA STATIC src/a.cpp)
set_property(TARGET libA PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_SOURCE_DIR}/include)add_library(libB STATIC src/b.cpp)
target_link_libraries(libB PUBLIC libA) # libA 的 INTERFACE 属性传递给 libBadd_executable(app src/main.cpp)
target_link_libraries(app PRIVATE libB) # app 自动获得 libA 的 include 目录
4.平台特定设置
add_executable(my_app src/main.cpp)if(WIN32)set_property(TARGET my_app PROPERTY WIN32_EXECUTABLE TRUE) # 创建 Windows GUI 应用
elseif(APPLE)set_property(TARGET my_app PROPERTY MACOSX_BUNDLE TRUE) # 创建 macOS 应用包
endif()
4.4.与高层级命令的对比与选择
场景 | 高层级命令 | 底层属性命令 | 选择建议 |
---|---|---|---|
添加编译选项 | target_compile_options | set_property(TARGET ...) | 简单场景用高层命令,复杂场景(如动态追加)用属性命令 |
设置链接库 | target_link_libraries | set_property(TARGET ...) | 优先使用高层命令,需直接操作 LINK_LIBRARIES 时用属性命令 |
控制输出名称 / 版本 | set_target_properties | set_property(TARGET ...) | 两者均可,属性命令更灵活(如动态设置) |
查询目标属性 | 无 | get_property(TARGET ...) | 只能用属性命令 |
5.源文件属性(Source File Properties)
源文件属性(Source File Properties) 允许开发者对单个源文件(如 .cpp
、.h
)进行精确配置,实现细粒度的编译控制。set_property
和 get_property
命令对源文件属性的操作,是处理特殊编译需求(如禁用特定警告、自定义预处理宏)的关键工具。
核心特点:
- 作用域:仅影响指定的单个或多个源文件。
- 优先级:源文件属性会覆盖目标级和目录级的相同属性设置。
- 典型用途:
- 为特定源文件添加编译选项(如禁用特定警告)。
- 设置源文件专属的预处理宏。
- 控制源文件是否参与编译(如条件排除)。
5.1.set_property
设置源文件属性
基本语法:
set_property(SOURCE <file1> [<file2> ...] PROPERTY <PROPERTY_NAME> <VALUE> [APPEND])
示例 1:为单个文件禁用特定警告
set_property(SOURCE src/third_party/legacy_code.cppPROPERTY COMPILE_OPTIONS "-Wno-deprecated-declarations"
)
示例 2:为文件设置专属预处理宏
set_property(SOURCE src/platform/win32.cppPROPERTY COMPILE_DEFINITIONS _WIN32_WINNT=0x0601
)
示例 3:标记文件为头文件(不参与编译)
set_property(SOURCE include/my_lib/api.hPROPERTY HEADER_FILE_ONLY TRUE
)
5.2.get_property
设置源文件属性
基本语法:
get_property(<VARIABLE> SOURCE <file> PROPERTY <PROPERTY_NAME> [SET])
示例 1:获取文件的编译选项
get_property(options SOURCE src/main.cpp PROPERTY COMPILE_OPTIONS)
message(STATUS "main.cpp 编译选项: ${options}")
示例 2:检查文件是否为头文件
get_property(is_header SOURCE include/my_lib.h PROPERTY HEADER_FILE_ONLY)
if(is_header)message(STATUS "my_lib.h 是头文件")
endif()
示例 3:获取文件的预处理宏
get_property(defines SOURCE src/debug.cpp PROPERTY COMPILE_DEFINITIONS)
message(STATUS "debug.cpp 预处理宏: ${defines}")
5.3.典型应用场景
1.编译选项定制
# 为特定平台文件添加编译选项
if(WIN32)set_property(SOURCE src/platform/win32_impl.cppPROPERTY COMPILE_OPTIONS "/wd4251" # 禁用 C4251 警告(dll 接口警告))
else()set_property(SOURCE src/platform/unix_impl.cppPROPERTY COMPILE_OPTIONS "-Wno-pedantic" # 禁用 pedantic 警告)
endif()
2.条件编译控制
# 根据配置选项启用/禁用特定源文件
option(ENABLE_FEATURE_X "启用特性 X" ON)
if(NOT ENABLE_FEATURE_X)set_property(SOURCE src/feature_x.cppPROPERTY HEADER_FILE_ONLY TRUE # 从编译中排除)
endif()
3.预处理宏设置
# 为测试文件设置测试模式宏
set_property(SOURCE tests/unit_tests.cppPROPERTY COMPILE_DEFINITIONS TEST_MODE=1
)
4.特殊文件处理
# 为汇编文件指定汇编器选项
set_property(SOURCE src/arch/x86_64/asm.SPROPERTY COMPILE_OPTIONS "-x assembler-with-cpp"
)
5.4.与其他作用域的对比
作用域 | 影响范围 | 典型应用场景 | 继承规则 |
---|---|---|---|
源文件 | 单个或多个指定文件 | 为特定文件禁用警告、设置专属宏 | 覆盖目标级和目录级属性 |
目标 | 整个目标(如可执行文件) | 为目标设置统一编译选项、链接库 | 可通过依赖传递给其他目标 |
目录 | 当前目录及所有子目录 | 目录级编译选项、包含路径设置 | 子目录可继承或覆盖父目录属性 |
6.缓存变量属性(Cache Variable Properties)
缓存变量属性(Cache Variable Properties) 用于控制 CMake 缓存变量的行为和元信息。set_property
和 get_property
命令对缓存变量属性的操作,允许开发者自定义变量的描述、高级选项状态、强制更新等特性。
核心特点:
- 作用域:影响 CMake 缓存中的全局变量(通过
set(... CACHE ...)
创建)。 - 存储位置:属性值保存在 CMakeCache.txt 文件中。
- 典型用途:
- 设置变量的用户友好描述(GUI 中显示)。
- 标记变量为高级选项(默认隐藏)。
- 控制变量的可见性和修改权限。
6.1.set_property
设置缓存变量属性
基本语法:
set_property(CACHE <variable> PROPERTY <PROPERTY_NAME> <VALUE>)
示例 1:设置变量描述
set(MY_OPTION ON CACHE BOOL "启用自定义选项")
set_property(CACHE MY_OPTION PROPERTY HELPSTRING "这是一个自定义选项,用于控制特性 X")
示例 2:标记为高级选项
set(ADVANCED_OPTION OFF CACHE BOOL "高级选项")
set_property(CACHE ADVANCED_OPTION PROPERTY ADVANCED TRUE) # 在 GUI 中默认隐藏
示例 3:设置变量验证正则表达式
set(BUILD_TYPE "Release" CACHE STRING "构建类型")
set_property(CACHE BUILD_TYPE PROPERTY STRINGS "Debug;Release;RelWithDebInfo;MinSizeRel")
6.2.get_property
获取缓存变量属性
基本语法:
get_property(<VARIABLE> CACHE <variable> PROPERTY <PROPERTY_NAME> [SET])
示例 1:获取变量描述
get_property(desc CACHE MY_OPTION PROPERTY HELPSTRING)
message(STATUS "MY_OPTION 描述: ${desc}")
示例 2:检查变量是否为高级选项
get_property(is_advanced CACHE ADVANCED_OPTION PROPERTY ADVANCED)
if(is_advanced)message(STATUS "ADVANCED_OPTION 是高级选项")
endif()
示例 3:获取变量的允许值列表
get_property(allowed_values CACHE BUILD_TYPE PROPERTY STRINGS)
message(STATUS "BUILD_TYPE 允许值: ${allowed_values}")
6.3.典型应用场景
1.自定义变量描述
set(CMAKE_BUILD_TYPE "Release" CACHE STRING "构建类型")
set_property(CACHE CMAKE_BUILD_TYPE PROPERTY HELPSTRING "选择构建类型 (Debug, Release, RelWithDebInfo, MinSizeRel)")
2.高级选项控制
option(ENABLE_PROFILING "启用性能分析" OFF)
set_property(CACHE ENABLE_PROFILING PROPERTY ADVANCED TRUE) # 仅在高级模式显示# 在 GUI 中,高级选项默认隐藏,需勾选 "Advanced" 按钮显示
3.变量验证与约束
set(COMPILER_OPTIMIZATION "O2" CACHE STRING "优化级别")
set_property(CACHE COMPILER_OPTIMIZATION PROPERTY STRINGS "O0;O1;O2;O3;Os") # 限制选择范围
set_property(CACHE COMPILER_OPTIMIZATION PROPERTY HELPSTRING "编译器优化级别")
4.变量初始化与强制更新
# 首次配置时设置默认值,后续不覆盖用户修改
if(NOT DEFINED CUSTOM_LIB_PATH)set(CUSTOM_LIB_PATH "/usr/local/lib" CACHE PATH "自定义库搜索路径")
endif()# 强制更新变量值(覆盖用户修改)
set(CMAKE_EXPORT_COMPILE_COMMANDS ON CACHE BOOL "导出编译命令" FORCE)
6.4.与普通变量的对比
特性 | 缓存变量(Cache Variable) | 普通变量(Regular Variable) |
---|---|---|
作用域 | 全局(所有 CMakeLists.txt 文件可见) | 局部(当前目录及子目录,除非使用 PARENT_SCOPE) |
存储位置 | CMakeCache.txt | 内存(仅在 CMake 运行期间有效) |
持久性 | 跨配置会话保留 | 每次运行 CMake 重新计算 |
适用场景 | 用户可配置选项、路径、全局开关 | 临时计算、内部变量、路径拼接 |
7.注意事项
1.作用域必须显式指定
- 错误:
set_property(PROPERTY ...)
(默认作用于DIRECTORY
,可能污染子目录) - 正确:
set_property(TARGET my_target PROPERTY ...)
2.
追加值时使用 APPEND
# 错误:直接设置会覆盖原有值
set_property(TARGET my_app PROPERTY COMPILE_OPTIONS "-O2")# 正确:追加新选项
set_property(TARGET my_app PROPERTY COMPILE_OPTIONS APPEND "-march=native")
3.避免频繁调用 get_property
可提前缓存属性值,减少重复查询:
get_property(common_files GLOBAL PROPERTY COMMON_SOURCES)
add_library(my_lib ${common_files} src/lib.cpp)
8.典型应用场景整合示例
# 项目配置文件(CMakeLists.txt)
cmake_minimum_required(VERSION 3.15)
project(MyProject VERSION 1.0.0)# 1. 设置全局编译选项(根据构建类型)
if(CMAKE_BUILD_TYPE STREQUAL "Release")set_property(GLOBAL PROPERTY COMPILE_OPTIONS "-O3 -DNDEBUG")
else()set_property(GLOBAL PROPERTY COMPILE_OPTIONS "-g -Wall")
endif()# 2. 定义库目标并设置属性
add_library(my_core STATIC src/core.cpp)
set_property(TARGET my_core PROPERTY VERSION ${PROJECT_VERSION})
set_property(TARGET my_core PROPERTY SOVERSION 1)# 3. 为平台特定源文件设置属性
if(UNIX)set_property(SOURCE src/platform/unix.cpp PROPERTY COMPILE_DEFINITIONS _UNIX)
elseif(WIN32)set_property(SOURCE src/platform/win32.cpp PROPERTY COMPILE_DEFINITIONS _WIN32)
endif()# 4. 可执行文件目标中获取库版本
add_executable(my_app src/main.cpp)
get_property(CORE_VERSION TARGET my_core PROPERTY VERSION)
set_property(TARGET my_app PROPERTY VERSION ${CORE_VERSION})# 5. 检查是否启用测试功能
option(BUILD_TESTS "构建测试" OFF)
if(BUILD_TESTS)enable_testing()add_subdirectory(tests)# 在tests目录中可通过get_property获取全局属性
endif()
9.总结
set_property
和 get_property
是 CMake 中操控属性的底层接口,允许开发者在目标、源文件、目录等不同粒度上定制构建行为。尽管高层级命令(如 target_*
)能满足多数场景,但底层属性命令在以下场景不可或缺:
- 源文件级精细配置(如单个文件的编译选项)
- 跨模块状态传递(通过全局属性)
- 动态查询已有配置以调整构建逻辑
- 操作非标准或自定义属性
掌握这两个命令后,可极大提升 CMake 项目的灵活性和可定制性,尤其适合复杂工程的条件化构建与平台适配。
相关链接
- CMake 官网 CMake - Upgrade Your Software Build System
- CMake 官方文档:CMake Tutorial — CMake 4.0.3 Documentation
- CMake 源码:https://github.com/Kitware/CMake
- CMake 源码:CMake · GitLab
- 中文版基础介绍: CMake 入门实战 | HaHack
- wiki: Home · Wiki · CMake / Community · GitLab
-
Modern CMake 简体中文版: Introduction · Modern CMake