cmake变量均为字符串或分号分隔列表,用set定义单值、多值、含空格值及显式分号列表;message调试输出支持多参数拼接和status模式;普通变量作用域受限,缓存变量通过cache持久化并可force覆盖。

要在CMakeLists.txt里让项目配置灵活可调、避免硬编码路径或编译选项,必须掌握变量定义和调试输出的基本方法。CMake中所有变量本质都是字符串或分号分隔的字符串列表,没有原生整数、布尔等类型,但可通过约定语义模拟布尔行为(如ON/OFF)。
用set定义变量
set是CMake中最核心的变量赋值指令,语法简洁但行为有细节差异。
方法一:定义单值字符串变量
直接写set(VarName value),value不带引号也默认为字符串。例如:set(PROJECT_VERSION 1.2.3) → 变量PROJECT_VERSION值为字符串"1.2.3"。
方法二:定义多值列表变量
空格分隔多个值,CMake自动用分号连接。例如:set(SOURCES main.cpp utils.hpp logger.cpp) → SOURCES实际存储为"main.cpp;utils.hpp;logger.cpp"。这一步不能加引号包裹整个列表,否则会变成单个含空格的字符串。
方法三:显式用分号构造列表set(SOURCES "main.cpp;utils.hpp;logger.cpp")效果与方法二等价,但注意引号必须完整包裹整个字符串,否则解析会出错。
方法四:定义含空格的单字符串
必须用引号包围,否则空格会被当作分隔符。例如:set(INSTALL_PREFIX "/opt/my app") → 错误,会被拆成两个值;正确写法是set(INSTALL_PREFIX "/opt/my app")。
【变量名只能含字母、数字、下划线,且大小写敏感】。像set(my-var value)或set(MyVar value)与set(myvar value)是三个不同变量。
用message查看变量值
message函数是调试CMake脚本最直接的手段,用于向终端打印内容,确认变量是否按预期设置。
CMake 4.3.2 Windows x86_64 历史版本安装包,适合旧项目兼容、构建环境回退、CMakeLists.txt 迁移验证、Visual Studio/Ninja/Makefile 生成器测试和 C/C++ 项目维护。
基础写法:message(${VarName})。如果VarName未定义,输出为空行;如果已定义,展开为其值。
推荐带上描述性前缀,避免纯值难以识别:message("PROJECT_VERSION = ${PROJECT_VERSION}")。
支持多参数拼接,各字符串自动连成一行:message("Sources:" ${SOURCES} "Count:" ${SOURCES_SIZE})。注意这里${SOURCES_SIZE}若未定义,就只显示空字符串,不会报错。
使用STATUS模式让输出更醒目:message(STATUS "Using compiler: ${CMAKE_CXX_COMPILER}"),会在前面加"-- "前缀,便于在大量CMake日志中快速定位。
区分普通变量与缓存变量
普通变量作用域默认限于当前CMakeLists.txt文件及其include()、function()内部,add_subdirectory()子目录会拷贝一份副本,修改不影响父目录。
缓存变量用于跨构建会话持久化配置,比如用户通过cmake-gui或命令行-D选项设置的选项。定义方式为:set(BUILD_TESTS ON CACHE BOOL "Enable tests")。其中CACHE后必须指定类型(BOOL/STRING/PATH等)和文档字符串。
【缓存变量一旦写入CMakeCache.txt,下次运行cmake时会优先读取该值,忽略set中的默认值】。若想强制覆盖,需加FORCE参数:set(BUILD_TESTS OFF CACHE BOOL "Enable tests" FORCE)。
环境变量访问用$ENV{PATH}语法,不是${PATH}——后者引用的是CMake普通变量,两者完全无关。










