5 分钟搞懂 CMake 变量:零基础也能学会的构建技巧
一、还在手撸 CMake?Out 啦!还在手动修改 CMakeLists.txt? 每次改个路径、换个编译器都要改半天? 那你就 Out 啦!
CMake 变量:让你解放双手,只需要修改一个变量,就能轻松切换编译选项、调整目标平台,甚至是更换编译器!就像给你的代码加上了“遥控器”,想怎么改就怎么改,而且还不容易出错!
5 分钟,从小白到入门: 这篇教程就是你的 CMake 变量入门指南,保证你 5 分钟就能上手,彻底告别手动修改的苦逼日子!
CMake 变量就是用来存储信息,并在构建过程中被 CMake 调用的!最简单的理解,CMake 变量就是一个名字,对应着一个值。CMake 在构建项目的时候,会根据这些变量的值来做出相应的操作。
比如可以把项目名称记录在一个名为 PROJECT_NAME 的变量里,然后在构建的时候引用它。
CMake 变量的作用:
可以用来存储各种信息,例如:
项目信息: 项目名称、版本号。
路径信息: 源文件目录、头文件目录、库文件目录。
编译选项: 编译标志 (例如 -Wall, -O2)、链接选项。
用来控制构建过程的各个方面,例如:
选择编译器: 指定使用哪个 C++ 编译器 (例如 GCC, Clang)。
设置编译选项: 开启或关闭优化、添加调试信息。
指定链接库: 告诉链接器要链接哪些库。
控制安装目录: 指定程序安装到哪个目录。
避免硬编码,提高构建过程的灵活性和可维护性。只需要修改变量的值,就可以改变构建行为,而无需修改大量的代码。
CMake 变量的类型:
类型描述示例常用场景注意:
CMake 对大小写不敏感 (变量名除外)。
CMake 会自动推断变量的类型,也可以显式指定。
这只是最常用的几种类型,CMake 还有其他更复杂的类型。
三、CMake 变量的设置使用 SET() 命令设置变量。语法:
SET(变量名 变量值 [FORCE])变量名: 变量的名称 (大小写不敏感,但建议大写)。
变量值: 变量的值,可以是一个字符串、列表或布尔值。
FORCE: (可选) 如果变量已经存在,则强制覆盖其值。
示例:
SET(MY_VARIABLE "Hello CMake") # 设置一个字符串变量 SET(SRC_FILES "main.cpp;utils.cpp") # 设置一个列表变量 SET(ENABLE_FEATURE TRUE) # 设置一个布尔变量 # 设置一个CACHE变量,类型为PATH SET(INSTALL_PREFIX "/usr/local" CACHE PATH "安装路径")CMake 变量有不同的作用域,决定了它们在 CMakeLists.txt 文件中的可见性和生命周期。
全局变量:
在顶级 CMakeLists.txt 文件中使用 SET() 设置的变量,默认情况下是全局变量。
全局变量在整个 CMake 项目中都可见 (包括子目录)。
全局变量的值可以在任何 CMakeLists.txt 文件中被修改。
函数/目录变量 (局部变量):
在函数或宏内部使用 SET(变量名 ...) 设置的变量,作用域仅限于该函数或宏内部。 函数或宏执行完毕后,这些变量就会失效。
在 add_subdirectory() 命令创建的子目录中的 CMakeLists.txt 文件中,也可以设置只在该目录及其子目录下有效的变量。这些变量不会影响父目录中的同名变量。
重要区别:
全局变量影响整个项目。
局部变量只影响函数/宏/目录内部。
四、CMake 变量的使用使用 ${} 可以展开变量的值。这是在 CMake 中获取变量值的标准方法。语法: ${变量名}
示例:
在编译选项中使用变量:
SET(MY_DEFINE "ENABLE_FEATURE") ADD_DEFINITIONS(-D${MY_DEFINE}) #相当于 -DENABLE_FEATURE或者,如果想要定义一个字符串值:
SET(MY_STRING_VALUE "My String") ADD_DEFINITIONS(-DSTRING_VALUE="${MY_STRING_VALUE}") # 相当于 -DSTRING_VALUE="My String"注意:如果变量包含空格或者特殊字符,使用双引号 "..." 包裹 ${MY_STRING_VALUE}。
在源文件路径中使用变量:
SET(MY_SOURCE_FILE "main") #存储不带后缀的文件名 ADD_EXECUTABLE(my_program src/${MY_SOURCE_FILE}.cpp)假如目录结构如下:
MyProject/ ├── CMakeLists.txt └── src/ ├── main.cpp └── utils.cpp示例,变量在 ADD_EXECUTABLE 或 ADD_LIBRARY 中的使用:
cmake_minimum_required(VERSION 3.10) project(MyProject) # 设置源文件列表的变量 SET(SOURCE_FILES src/main.cpp src/utils.cpp ) # 设置库的名称的变量 SET(LIBRARY_NAME "mylibrary") # 创建可执行文件 ADD_EXECUTABLE(my_program ${SOURCE_FILES}) # 创建静态库 ADD_LIBRARY(${LIBRARY_NAME} STATIC ${SOURCE_FILES}) # 创建动态库 (共享库) ADD_LIBRARY(${LIBRARY_NAME}_shared SHARED ${SOURCE_FILES})总结:$ {} 是展开变量值的关键。
五、常见 CMake 变量项目信息:
变量名描述常见用途备注构建类型和编译器:
变量名描述常见用途备注安装路径:
变量名描述常见用途备注编译/链接选项:
变量名描述常见用途备注系统信息和特性
变量名描述常见用途备注其他有用的变量:
变量名描述常见用途备注更多内容查阅 CMake 官方文档以获取更完整的变量列表和详细信息:https://cmake.org/documentation/
尽量使用 target_* 系列命令 (例如 target_compile_options, target_link_libraries) 为特定的构建目标设置属性,而不是全局设置 CMAKE_* 变量,以避免不必要的副作用。
六、总结本文深入探讨了 CMake 变量,CMake 变量是 CMake 构建系统中的核心组成部分,它们控制着项目的配置、构建和安装过程。
CMake 变量用于存储各种信息,例如项目名称、版本号、编译器路径、编译选项、安装路径等等。通过实践,能够更好地理解 CMake 变量的作用,并掌握更高级的 CMake 技术。
参考资源: