CMake 变量与缓存
本章将介绍 CMake 的变量系统和缓存机制,这是理解 CMake 配置过程的关键。
变量基础
set 命令
# 设置变量
set(VAR_NAME value)
# 取消变量
unset(VAR_NAME)
# 设置环境变量
set(ENV{PATH} "/new/path:$ENV{PATH}")
变量引用
set(NAME "World")
message("Hello, ${NAME}!") # Hello, World!
# 嵌套引用
set(VAR_NAME "MESSAGE")
set(${VAR_NAME} "Hello") # 等同于 set(MESSAGE "Hello")
message("${MESSAGE}") # Hello
变量作用域
# 全局变量
set(GLOBAL_VAR "global")
function(my_func)
# 函数局部变量
set(LOCAL_VAR "local")
message("Inside: ${LOCAL_VAR}") # local
# 修改父作用域变量
set(GLOBAL_VAR "modified" PARENT_SCOPE)
endfunction()
my_func()
message("Outside: ${GLOBAL_VAR}") # modified
内置变量
项目信息变量
# 项目相关
PROJECT_NAME # 项目名称
PROJECT_VERSION # 项目版本
PROJECT_SOURCE_DIR # 项目源码目录
PROJECT_BINARY_DIR # 项目构建目录
# CMake 相关
CMAKE_SOURCE_DIR # 顶层源码目录
CMAKE_BINARY_DIR # 顶层构建目录
CMAKE_CURRENT_SOURCE_DIR # 当前 CMakeLists.txt 所在目录
CMAKE_CURRENT_BINARY_DIR # 当前构建目录
CMAKE_VERSION # CMake 版本
构建相关变量
# 编译器
CMAKE_C_COMPILER # C 编译器
CMAKE_CXX_COMPILER # C++ 编译器
CMAKE_BUILD_TYPE # 构建类型
# 标志
CMAKE_C_FLAGS # C 编译标志
CMAKE_CXX_FLAGS # C++ 编译标志
CMAKE_EXE_LINKER_FLAGS # 可执行文件链接标志
# 平台
CMAKE_SYSTEM_NAME # 系统名称(Linux, Windows, Darwin)
WIN32 # Windows 平台(布尔)
UNIX # Unix 平台(布尔)
APPLE # Apple 平台(布尔)
安装相关变量
CMAKE_INSTALL_PREFIX # 安装前缀
CMAKE_INSTALL_BINDIR # 可执行文件目录
CMAKE_INSTALL_LIBDIR # 库文件目录
CMAKE_INSTALL_INCLUDEDIR # 头文件目录
缓存变量
缓存变量存储在 CMakeCache.txt 文件中,在多次运行 CMake 时保持值。
基本语法
set(VAR_NAME value CACHE TYPE "description" [FORCE])
缓存类型
| 类型 | 说明 |
|---|---|
| BOOL | 布尔值(ON/OFF) |
| STRING | 字符串 |
| PATH | 文件路径 |
| FILEPATH | 文件路径 |
| INTERNAL | 内部变量(不在 GUI 显示) |
示例
# 布尔选项
option(ENABLE_TESTS "Enable unit tests" ON)
# 字符串选项
set(DEFAULT_PORT "8080" CACHE STRING "Default server port")
# 路径选项
set(INSTALL_DIR "/usr/local" CACHE PATH "Installation directory")
# 强制更新缓存
set(FORCE_UPDATE "new_value" CACHE STRING "" FORCE)
检查和设置
# 检查变量是否在缓存中定义
if(NOT DEFINED CACHE{MY_VAR})
set(MY_VAR "default" CACHE STRING "My variable")
endif()
# 从缓存中获取
set(CACHED_VALUE "$CACHE{MY_VAR}")
环境变量
# 读取环境变量
set(PATH_VALUE "$ENV{PATH}")
# 设置环境变量(仅构建过程)
set(ENV{MY_VAR} "value")
# 检查环境变量
if(DEFINED ENV{HOME})
message("Home: $ENV{HOME}")
endif()
列表操作
set(MY_LIST a b c)
# 追加
list(APPEND MY_LIST d e) # a;b;c;d;e
# 插入
list(INSERT MY_LIST 0 x) # x;a;b;c;d;e
# 移除
list(REMOVE_ITEM MY_LIST b) # x;a;c;d;e
list(REMOVE_AT MY_LIST 0) # a;c;d;e
# 排序
list(SORT MY_LIST)
# 反转
list(REVERSE MY_LIST)
# 获取长度
list(LENGTH MY_LIST len)
# 获取元素
list(GET MY_LIST 0 first)
list(GET MY_LIST 1 2 subset)
属性
全局属性
set_property(GLOBAL PROPERTY MY_GLOBAL_PROP "value")
get_property(result GLOBAL PROPERTY MY_GLOBAL_PROP)
目录属性
set_property(DIRECTORY PROPERTY MY_DIR_PROP "value")
目标属性
set_target_properties(myapp PROPERTIES
CXX_STANDARD 17
OUTPUT_NAME "application"
)
get_target_property(STD myapp CXX_STANDARD)
小结
本章我们学习了:
- 变量基础:set、unset、变量引用
- 内置变量:项目、构建、平台相关变量
- 缓存变量:CACHE 类型、option 命令
- 环境变量:ENV 语法
- 列表操作:APPEND、REMOVE、SORT 等
- 属性系统:全局、目录、目标属性
练习
- 创建一个可配置的项目选项(使用 option 和缓存)
- 使用列表管理源文件
- 编写条件判断,根据缓存变量决定是否启用功能