跳到主要内容

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)

小结

本章我们学习了:

  1. 变量基础:set、unset、变量引用
  2. 内置变量:项目、构建、平台相关变量
  3. 缓存变量:CACHE 类型、option 命令
  4. 环境变量:ENV 语法
  5. 列表操作:APPEND、REMOVE、SORT 等
  6. 属性系统:全局、目录、目标属性

练习

  1. 创建一个可配置的项目选项(使用 option 和缓存)
  2. 使用列表管理源文件
  3. 编写条件判断,根据缓存变量决定是否启用功能