您的位置:首页 > 财经 > 产业 > 北京网站建设有限公司_编写网站用什么语言_廊坊seo关键词优化_互联网产品推广是做什么的

北京网站建设有限公司_编写网站用什么语言_廊坊seo关键词优化_互联网产品推广是做什么的

2025/6/19 23:02:25 来源:https://blog.csdn.net/JuicyActiveGilbert/article/details/146248666  浏览:    关键词:北京网站建设有限公司_编写网站用什么语言_廊坊seo关键词优化_互联网产品推广是做什么的
北京网站建设有限公司_编写网站用什么语言_廊坊seo关键词优化_互联网产品推广是做什么的

源码及CMakeLists.txt沿用第1篇或第2篇的均可,本文沿用第2篇的相关文件

1. CMake变量的基础操作

1.1 定义与修改变量

在CMakeLists.txt后面加入如下代码:

# 定义普通变量
set(MY_VAR "Hello World")
# 修改变量值
set(MY_VAR "New Value")
# 列表变量(分号分隔)
set(MY_LIST a.cpp b.cpp c.cpp)
# 或显式列表
set(MY_LIST "a.cpp;b.cpp;c.cpp")# 打印变量内容
message("变量值: ${MY_VAR}")  # 输出: 变量值: New Value
# 打印列表内容
message("列表内容: ${MY_LIST}")  # 输出: 列表内容: a.cpp;b.cpp;c.cpp

执行cmake --build .可在结果编译的输出信息中找到对应的输出,如下图:
在这里插入图片描述

1.2 删除变量

unset(MY_VAR)  # 删除当前作用域的变量

2. 变量的作用域层级

修改目录结构如下:

hello_cmake/├── CMakeLists.txt├── include/│   └── utils.h├── src/│   ├── utils.cpp│   └── main.cpp└── build/└── subdir/│   └── CMakeLists.txt

2.1 目录作用域(Directory Scope)

# 父目录的CMakeLists.txt
set(PARENT_VAR "Parent Value")
add_subdirectory(subdir)
message("父目录中读取被改变的变量: ${PARENT_VAR}")  # 可读取
# 子目录subdir/CMakeLists.txt
message("子目录读取父变量: ${PARENT_VAR}")    # 可读取
set(PARENT_VAR "Child Modified" PARENT_VAR)  # 修改父作用域的变量

输出结果如下:
在这里插入图片描述

作用域规则
  • ​父目录的变量在子目录中是只读副本,子目录对变量的修改不会影响父目录。
  • 每个 add_subdirectory() 都会创建一个新的作用域(类似函数调用)。
修改父目录变量的方法
  • 在子目录中使用 set(... PARENT_SCOPE) 将变量传递到父作用域。
  • 缓存变量是全局的,所有作用域共享。
# 父目录 CMakeLists.txt
set(MY_CACHE_VAR "初始值" CACHE STRING "说明")# 子目录 subdir/CMakeLists.txt
set(MY_CACHE_VAR "新值" CACHE STRING "说明" FORCE)  # 强制修改缓存变量
message("子目录中的 MY_CACHE_VAR = ${MY_CACHE_VAR}")  # 输出 "新值"
  • 使用全局属性(set_property)​
# 父目录 CMakeLists.txt
set_property(GLOBAL PROPERTY MY_GLOBAL_VAR "初始值")# 子目录 subdir/CMakeLists.txt
get_property(tmp GLOBAL PROPERTY MY_GLOBAL_VAR)
set_property(GLOBAL PROPERTY MY_GLOBAL_VAR "${tmp}_子目录修改")

2.2 函数/宏作用域

function(my_function)set(LOCAL_VAR "Local Value" PARENT_SCOPE)  # 修改上级作用域
endfunction()my_function()
message("函数外部: ${LOCAL_VAR}")  # 输出: 函数外部: Local Value

2.3 目标作用域(Target Scope)

add_library(mylib STATIC mylib.cpp)# 仅对mylib目标生效
target_compile_definitions(mylib PRIVATE DEBUG_MODE=1)

3. 缓存变量(CACHE Variables)详解

3.1 定义缓存变量

# 语法:set(<变量名> <> CACHE <类型> <描述> [FORCE])
set(BUILD_TESTS OFF CACHE BOOL "是否启用测试")# 高级用法:下拉选项
set(COMPILER_TYPE "GCC" CACHE STRING "选择编译器")
set_property(CACHE COMPILER_TYPE PROPERTY STRINGS "GCC;Clang;MSVC")

以上的修改在纯命令行编译时无法体型,在CMake GUI中可以看到会增加对应的可选项。
在这里插入图片描述

3.2 修改与覆盖

命令行覆盖

cmake -DBUILD_TESTS=ON ..

脚本强制修改

set(BUILD_TESTS ON CACHE BOOL "覆盖值" FORCE)

3.3 缓存变量类型

类型​描述​示例​适用场景 ​GUI显示形式
​BOOL布尔值,表示开关选项(ON/OFF)。set(USE_FEATURE_X ON CACHE BOOL “…”)控制功能开关(如 ENABLE_TESTING)。复选框(Checkbox)。
​STRING普通字符串,可配合 STRINGS 属性限定可选值。set(BUILD_TYPE “Debug” CACHE STRING “…”)配置构建类型(如 Debug/Release)。下拉框(若定义了 STRINGS 属性)。
​PATH表示文件系统目录路径,CMake GUI 提供路径选择按钮。set(INSTALL_PREFIX “/usr/local” CACHE PATH “…”)指定安装目录、依赖库路径等。路径选择对话框(带浏览按钮)。
​FILEPATH表示文件路径,CMake GUI 提供文件选择按钮。set(CONFIG_FILE “config.cfg” CACHE FILEPATH “…”)指定配置文件、输入文件路径。文件选择对话框(带浏览按钮)。
​INTERNAL内部变量,不在 GUI 中显示,但值会持久化到缓存。set(INTERNAL_CACHE “secret” CACHE INTERNAL “…”)存储内部配置(如哈希值、临时标记)。不显示。
​STATIC静态描述文本,仅用于在 GUI 中分组或注释(实际不存储值)。set(HELP_TEXT “Options:” CACHE STATIC “…”)GUI 界面中的分组标题或说明文本。只读文本标签。

4. 环境变量操作

4.1 读取系统环境变量

# 读取PATH环境变量
message("系统PATH: $ENV{PATH}")# 在代码中使用(通过编译定义传递)
add_definitions(-DMY_ENV_PATH="$ENV{PATH}")

4.2 设置临时环境变量

# 仅影响当前CMake进程
set(ENV{CFLAGS} "-O2")

5. 实战技巧与避坑指南

5.1 变量优先级规则

普通变量 > 缓存变量(无FORCE时) > 环境变量

5.2 避免变量污染

# 错误示例:全局变量污染
set(SOURCES main.cpp)  # 全局作用域# 正确做法:限定作用域
function(add_module)set(SOURCES a.cpp b.cpp)  # 函数作用域add_library(mymodule ${SOURCES})
endfunction()

5.3 类型转换技巧

# 字符串转列表
string(REPLACE ";" " " MY_STR "${MY_LIST}")  # "a.cpp b.cpp c.cpp"# 列表操作
list(APPEND MY_LIST d.cpp)    # 添加元素
list(REMOVE_ITEM MY_LIST a.cpp) # 删除元素

6. 常见问题解答

Q1:CACHE变量和普通变量有什么区别?

  • CACHE变量:持久化存储(写入CMakeCache.txt),可跨多次配置
  • 普通变量:临时存在,作用域结束后销毁

Q2:如何强制刷新缓存变量?

  • 删除build目录或使用cmake -U <变量名>清除
  • 在脚本中用FORCE关键字

Q3:为什么我的变量在子目录中不可见?

  • 默认变量传递是向下传递的,向上修改需用PARENT_SCOPE
  • 跨目录共享变量建议用CACHE变量

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com