一、介绍

set命令可以设置普通变量、缓存条目、环境变量三种变量的值,分别对应以下三种命令格式。set的值<value>...表示可以给变量设置0个或者多个值,当设置多个值时(大于2个),多个值会通过分号连接符连接成一个真实的值赋值给变量,当设置0个值时,实际上是把变量变为未设置状态,相当于调用unset命令。

set(<variable> <value>... [PARENT_SCOPE]) #设置普通变量

set(<variable> <value>... CACHE <type> <docstring> [FORCE]) #设置缓存条目

set(ENV{<variable>} [<value>]) #设置环境变量

二、使用

1)设置变量为一个给定的值

cmake_minimum_required (VERSION 3.10.2)

project (set_test)

set (normal_var a)

message (">>> value = ${normal_var}")

打印

2)设置变量为多个给定的值

cmake_minimum_required (VERSION 3.10.2)

project (set_test)

set (normal_var a b c)

message (">>> value = ${normal_var}")

 打印

3)设置变量为空

cmake_minimum_required (VERSION 3.10.2)

project (set_test)

set (normal_var a b c)

message (">>> value = ${normal_var}")

set (normal_var) # 设置变量为空

message (">>> value = ${normal_var}")

 打印

4)如果在函数中使用set,则set的范围只在该函数内,调用它的函数并不能获取到该变量,类似于C++变量的作用域

function (test_fn arg1)
    set (normal_var_in_fn ${arg1})
    message (">>> in function, value = ${normal_var_in_fn}")
endfunction (test_fn)

function (test_fn_parent arg1)
    test_fn (${arg1})
    message (">>> in parent function, value = ${normal_var_in_fn}")
endfunction (test_fn_parent)

test_fn_parent (hello)

 

如果是在调用函数中定义变量,子函数还是可以获取到该变量

function (test_fn arg1)
    message (">>> in function, value = ${normal_var_in_fn}")
endfunction (test_fn)

function (test_fn_parent arg1)
    set (normal_var_in_fn ${arg1})
    test_fn (${arg1})
    message (">>> in parent function, value = ${normal_var_in_fn}")
endfunction (test_fn_parent)

test_fn_parent (hello)

 这里有个特殊的场景,如果set使用了选项PARENT_SCOPE,则变量的作用域只能传递到调用它的函数,它定义的函数中却没有该变量

举个例子,在函数(示例中为test_fn)内使用set定义变量,并且加上选项PARENT_SCOPE。在调用者函数(示例中为test_fn_parent)内调用该函数。
结果:调用者函数内有该变量的定义,而使用者函数中却没有该变量的定义。
结论:选项PARENT_SCOPE将变量传递到上一层调用函数,而本层函数中没有该变量。

# CMakeLists.txt
cmake_minimum_required (VERSION 3.10.2)
project (set_test)

function (test_fn arg1)
    set (normal_var_in_fn ${arg1} PARENT_SCOPE)
    message (">>> in function, value = ${normal_var_in_fn}")
endfunction (test_fn)

function (test_fn_parent arg1)
    test_fn (${arg1})
    message (">>> in parent function, value = ${normal_var_in_fn}")
endfunction (test_fn_parent)

test_fn_parent (hello)

打印

同时使用set,PARENT_SCOPE

function (test_fn arg1)
    set (normal_var_in_fn ${arg1} PARENT_SCOPE) #在内部定义
    message (">>> in function, value = ${normal_var_in_fn}")
endfunction (test_fn)

function (test_fn_parent arg1)
    set (normal_var_in_fn ${arg1}) #先在外部定义
    test_fn (kkk)
    message (">>> in parent function, value = ${normal_var_in_fn}")
endfunction (test_fn_parent)

test_fn_parent (hello)

打印

 

 

 三、设置缓存条目

相当于一个全局变量,我们在同一个 cmake 工程中都可以使用

  命令格式

set(<variable> <value>... CACHE <type> <docstring> [FORCE])

命令含义:将缓存条目variable设置为值<value>...,除非用户进行设置或使用了选项FORCE,默认情况下缓存条目的值不会被覆盖。缓存条目可以通过CMAKE的GUI界面的add entry按钮来增加。缓存条目的实质为可以跨层级进行传递的变量,类似于全局变量。

缓存条目的<type>主要有以下几类:

  • BOOL:布尔值ON/OFF,CMAKE的GUI界面对此类缓存条目会提供一个复选框。
  • FILEPATH:文件路径,CMAKE的GUI界面对此类缓存条目会提供一个文件选择框。
  • PATH:目录路径,CMAKE的GUI界面对此类缓存条目会提供一个目录选择框。
  • STRING / STRINGS:文本行,CMAKE的GUI界面对此类缓存条目会提供一个文本框(对应STRING)或下拉选择框(对应STRINGS)。
  • INTERNAL:文本行,但是只用于内部,不对外呈现。主要用于运行过程中存储变量,因此使用该type意味着使用FORCE
      缓存条目的几个注意事项:
    1)如果变量先前未定义或者使用了FORCE选项,则缓存条目会直接被赋值。
    2)可以在使用cmake构建的使用通过-D选项来给缓存条目赋值,这样CMakeLists.txt内的set命令只会为缓存条目添加类型。
    3)如果变量类型是目录或者文件路径,通过-D选项传入的若只是相对路径,那么set会给这个相对路径前添加当前的工作目录以变成绝对路径(如果已经是绝对路径则不会处理)。
# CMakeLists.txt
cmake_minimum_required (VERSION 3.10.2)
project (set_test)

set (cache_entry_val ON OFF CACHE BOOL "choose ON to enable")
message (">>> value = ${cache_entry_val}")

set (cache_entry_val2 ON CACHE BOOL "choose ON to enable" FORCE)
message (">>> value2 = ${cache_entry_val2}")

set (cache_entry_val3 ON)
set (cache_entry_val3 OFF CACHE BOOL "choose ON to enable")
message (">>> value3 = ${cache_entry_val3}")

set (cache_entry_input OFF CACHE BOOL "choose ON to enable")
message (">>> value4 = ${cache_entry_input}")

set (mypath "test" CACHE FILEPATH "choose a file path")
message (">>> value5 = ${mypath}")

打印

四. 设置环境变量

  命令格式set(ENV{<variable>} [<value>])
  命令含义:将环境变量设置为值<value>(注意没有...),接着使用$ENV{<variable>}会得到新的值。cmake中的环境变量可以参考:环境变量
  环境变量设置的几个注意事项:
1)该命令设置的环境变量只在当前的cmake进程生效,既不会影响调用者的环境变量,也不会影响系统环境变量。
2)如果<value>值为空或者ENV{<variable>}后没有参数,则该命令会清除掉当前环境变量的值。
3)<value>后的参数会被忽略。

# CMakeLists.txt
cmake_minimum_required (VERSION 3.10.2)
project (set_test)

message (">>> value = $ENV{CMAKE_PREFIX_PATH}")

set (ENV{CMAKE_PREFIX_PATH} "/test/sub")
message (">>> value = $ENV{CMAKE_PREFIX_PATH}")

set (ENV{CMAKE_PREFIX_PATH})
message (">>> value = $ENV{CMAKE_PREFIX_PATH}")

set (ENV{CMAKE_PREFIX_PATH} "/test/top/") 
message (">>> value = $ENV{CMAKE_PREFIX_PATH}")

set (ENV{CMAKE_PREFIX_PATH} "") 
message (">>> value = $ENV{CMAKE_PREFIX_PATH}")

打印

参考:

set — CMake 3.22.2 Documentation

Cmake命令之set介绍 - 简书

CMake 两种变量原理 - 小北师兄 - 博客园

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐