• C++-Cmake指令:set


    • 命令格式

      set( ... [PARENT_SCOPE]) #设置普通变量
      set( ... CACHE [FORCE]) #设置缓存条目
      set(ENV{} []) #设置环境变量

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

    • 命令解析

      下面分别对三种变量的设置进行说明。

      1. 设置普通变量

        命令格式set( ... [PARENT_SCOPE])
        命令含义:将变量variable设置为值...,变量variable作用域为调用set命令的函数或者当前目录,如果使用了PARENT_SCOPE选项,意味着该变量的作用域会传递到上一层(也就是上一层目录或者当前函数的调用者,如果是函数则传递到函数的调用者,如果是目录则传递到上一层目录),并且在当前作用域该变量不受带PARENT_SCOPE选项的set命令的影响(如果变量之前没有定义,那么在当前作用域仍然是无定义的;如果之前有定义值,那么值和之前定义的值保持一致)。
        关于变量的作用域:每一个新的目录或者函数都会创建一个新的作用域,普通变量的作用域,如果不使用PARENT_SCOPE选项,只能从外层往内层传递。

      • 1)先来看最常用的用法,设置变量为一个给定的值
      1. cmake_minimum_required (VERSION 3.10.2)
      2. project (set_test)
      3. set (normal_var a)
      4. message (">>> value = ${normal_var}")

        输出为:

      >>> value = a
      
      • 2)设置变量为多个给定的值
      1. cmake_minimum_required (VERSION 3.10.2)
      2. project (set_test)
      3. set (normal_var a b c)
      4. message (">>> value = ${normal_var}")

        输出为:

      >>> value = a;b;c
      

        可以看到多个值被;号连接最终的值之后赋给变量。

      • 3)设置变量为空
      1. cmake_minimum_required (VERSION 3.10.2)
      2. project (set_test)
      3. set (normal_var a b c)
      4. message (">>> value = ${normal_var}")
      5. set (normal_var) # 设置变量为空
      6. message (">>> value = ${normal_var}")

        输出为:

      1. >>> value = a;b;c
      2. >>> value =
      • 4)在函数内使用选项PARENT_SCOPE,对应的作用域只能传递到调用它的函数。
        场景1:在函数内使用选项PARENT_SCOPE定义变量,在函数定义的文件中(非另一个函数中)使用该变量。
        结果:变量无定义。
        结论:函数内定义的变量,在函数定义的文件中调用,找不到变量的定义。
        1. # CMakeLists.txt
        2. cmake_minimum_required (VERSION 3.10.2)
        3. project (set_test)
        4. function (test_fn arg1)
        5. set (normal_var_in_fn ${arg1} PARENT_SCOPE)
        6. endfunction (test_fn)
        7. message (">>> in directory, value = ${normal_var_fn}")
        1. # 输出
        2. >>> in directory, value =
        3. >>> in function, value =
        场景2:在函数内使用选项PARENT_SCOPE定义变量,在函数内使用该变量。
        结果:变量无定义。
        结论:函数内使用选项PARENT_SCOPE定义的变量,在函数内也是无定义的。
        1. # CMakeLists.txt
        2. cmake_minimum_required (VERSION 3.10.2)
        3. project (set_test)
        4. function (test_fn arg1)
        5. set (normal_var_in_fn ${arg1} PARENT_SCOPE)
        6. message (">>> in function, value = ${normal_var_fn}")
        7. endfunction (test_fn)
        8. test_fn (hello)
        1. # 输出
        2. >>> in function, value =
        场景3:在函数内使用选项PARENT_SCOPE定义变量,在函数内使用该变量,并且使用set命令不带PARENT_SCOPE选项定义过该变量。
        结果:函数内的变量值为不带PARENT_SCOPE选项的set命令所定义的。
        结论:选项PARENT_SCOPE定义的变量作用域在上一层函数,当前函数的变量必须使用不带选项PARENT_SCOPE定义。
        1. # CMakeLists.txt
        2. cmake_minimum_required (VERSION 3.10.2)
        3. project (set_test)
        4. function (test_fn arg1)
        5. set (normal_var_in_fn nohello)
        6. set (normal_var_in_fn ${arg1} PARENT_SCOPE)
        7. message (">>> in function, value = ${normal_var_in_fn}")
        8. endfunction (test_fn)
        9. test_fn (hello)
        1. # 输出
        2. >>> in function, value = nohello
        场景4:在函数(示例中为test_fn)内使用选项PARENT_SCOPE定义变量,在另一个函数(调用者,示例中为test_fn_parent)内调用该函数。
        结果:调用者函数内有该变量的定义。
        结论:选项PARENT_SCOPE将变量传递到上一层调用函数。
        1. # CMakeLists.txt
        2. cmake_minimum_required (VERSION 3.10.2)
        3. project (set_test)
        4. function (test_fn arg1)
        5. set (normal_var_in_fn nohello)
        6. set (normal_var_in_fn ${arg1} PARENT_SCOPE)
        7. message (">>> in function, value = ${normal_var_in_fn}")
        8. endfunction (test_fn)
        9. function (test_fn_parent arg1)
        10. test_fn (${arg1})
        11. message (">>> in parent function, value = ${normal_var_in_fn}")
        12. endfunction (test_fn_parent)
        13. test_fn_parent (hello)
        1. # 输出
        2. >>> in function, value = nohello
        3. >>> in parent function, value = hello
      • 5)在目录内使用选项PARENT_SCOPE,对应的作用域只能传递到上层目录,变量的传递过程与4)中函数的场景类似,不再赘述。注意一点:本例在testtest/sub下分别创建一个CMakeLists.txt文件。
        示例如下:
        1. # test/sub/CMakeLists.txt
        2. cmake_minimum_required (VERSION 3.10.2)
        3. project (set_sub_test)
        4. set (normal_var_in_sub_dir sub_hello)
        5. set (normal_var_in_sub_dir hello PARENT_SCOPE)
        6. message (">>>>>> in sub directory, value = ${normal_var_in_sub_dir}")
        1. # test/CMakeLists.txt
        2. cmake_minimum_required (VERSION 3.10.2)
        3. project (set_test)
        4. add_subdirectory (sub)
        5. message (">>> in top level, value = ${normal_var_in_sub_dir}")
        1. # 输出
        2. >>>>>> in sub directory, value = sub_hello
        3. >>> in top level, value = hello

      2. 设置缓存条目

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

      • 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会给这个相对路径前添加当前的工作目录以变成绝对路径(如果已经是绝对路径则不会处理)。
        1. # CMakeLists.txt
        2. cmake_minimum_required (VERSION 3.10.2)
        3. project (set_test)
        4. set (cache_entry_val ON OFF CACHE BOOL "choose ON to enable")
        5. message (">>> value = ${cache_entry_val}")
        6. set (cache_entry_val2 ON CACHE BOOL "choose ON to enable" FORCE)
        7. message (">>> value2 = ${cache_entry_val2}")
        8. set (cache_entry_val3 ON)
        9. set (cache_entry_val3 OFF CACHE BOOL "choose ON to enable")
        10. message (">>> value3 = ${cache_entry_val3}")
        11. set (cache_entry_input OFF CACHE BOOL "choose ON to enable")
        12. message (">>> value4 = ${cache_entry_input}")
        13. set (mypath "test" CACHE FILEPATH "choose a file path")
        14. message (">>> value5 = ${mypath}")
        1. # 输入cmake构建,使用-D选项
        2. cmake . -Dcache_entry_input=ON -Dmypath=sub
        3. # 输出
        4. >>> value = ON;OFF
        5. >>> value2 = ON
        6. >>> value3 = ON
        7. >>> value4 = ON
        8. >>> value5 = /XXX/XXX/XXX/sub

      3. 设置环境变量

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

      1. # CMakeLists.txt
      2. cmake_minimum_required (VERSION 3.10.2)
      3. project (set_test)
      4. message (">>> value = $ENV{CMAKE_PREFIX_PATH}")
      5. set (ENV{CMAKE_PREFIX_PATH} "/test/sub")
      6. message (">>> value = $ENV{CMAKE_PREFIX_PATH}")
      7. set (ENV{CMAKE_PREFIX_PATH})
      8. message (">>> value = $ENV{CMAKE_PREFIX_PATH}")
      9. set (ENV{CMAKE_PREFIX_PATH} "/test/top/")
      10. message (">>> value = $ENV{CMAKE_PREFIX_PATH}")
      11. set (ENV{CMAKE_PREFIX_PATH} "")
      12. message (">>> value = $ENV{CMAKE_PREFIX_PATH}")
      1. # 输出
      2. >>> value =
      3. >>> value = /test/sub
      4. >>> value =
      5. >>> value = /test/top
      6. >>> value =


    Cmake命令之set介绍 - 简书

  • 相关阅读:
    每天一个数据分析题(三百七十九)- 用户留存
    HTTP与SOCKS-哪种协议更适合您的代理需求?
    DOCTYPE是什么,有何作用、 使用方式、渲染模式、严格模式和怪异模式的区别?
    win server 2016 无法安转.net framework 3.5 问题
    .Net大数据平台Microsoft.Spark环境构建 附可运行源码。
    摸鱼工具 100行代码实现单号转换工具
    用DIV+CSS技术制作一个简单的网页 我的家乡主题
    Java基础教程详解:多线程(1)-----多线程概念
    【深度学习】 Python 和 NumPy 系列教程(廿七):Matplotlib详解:3、多子图和布局:散点矩阵图(Scatter Matrix Plot)
    【等级测评师】等级测评师怎么报名?多少分及格?
  • 原文地址:https://blog.csdn.net/u013250861/article/details/127935971