cmake变量使用

在编写CMake脚本时,您需要了解很多关于CMake中的语法和如何使用变量的知识。

句法

字符串使用set():

  • set(MyString "Some Text")

  • set(MyStringWithVar "Some other Text: ${MyString}")

  • set(MyStringWithQuot "Some quote: \"${MyStringWithVar}\"")

或与string():

  • string(APPEND MyStringWithContent " ${MyString}")

列表使用set():

  • set(MyList "a" "b" "c")

  • set(MyList ${MyList} "d")

或更好地与.list():

  • list(APPEND MyList "a" "b" "c")

  • list(APPEND MyList "d")

文件名列表:

  • set(MySourcesList "File.name" "File with Space.name")0

  • list(APPEND MySourcesList "File.name" "File with Space.name")

  • add_excutable(MyExeTarget ${MySourcesList})

范围或“我的变量有什么值?”

首先,有一些“正常变量”,以及您需要知道的关于它们的范围的事情:

  • 普通变量对CMakeLists.txt他们被安置在里面,一切都从那里召唤(add_subdirectory()include()macro()function()).
  •  
  • 这个add_subdirectory()和function()命令是特殊的,因为它们打开了自己的作用域。
    • 设置变量

      set(...)

      只有在那里是可见的,它们复制了它们从作用域级别调用的所有普通变量(称为父作用域)。
    • 因此,如果您位于子目录或函数中,则可以在父作用域中修改已存在的变量。

      set(... PARENT_SCOPE)

    • 您可以通过将变量名作为函数参数来使用,例如在函数中。一个例子就是

      function(xyz _resultVar)

      正在设置

      set(${_resultVar} 1 PARENT_SCOPE)

  • 另一方面,你所做的一切

    include()

    macro()

    脚本将在调用它们的位置的范围内直接修改变量。

其次是“全局变量缓存”。关于缓存你需要知道的事情:

  • 如果在当前范围中没有定义具有给定名称的普通变量,CMake将查找匹配的Cache条目。
  • 缓存值存储在

    CMakeCache.txt

    文件在二进制输出目录中。
  • 缓存中的值可以在CMake图形用户界面在生成它们之前应用程序。因此,与普通变量相比,它们具有一个type和一个docstring..我通常不使用GUI,所以我使用set(... CACHE INTERNAL "")来设置我的全局和持久的价值观。

    请注意,INTERNAL缓存变量类型确实意味着FORCE

  • 在CMake脚本中,只有在使用set(... CACHE ... FORCE)语法。这个行为是由CMake本身使用的,因为它通常不会强制缓存条目本身,因此您可以用另一个值预定义它。

  • 可以使用命令行使用语法设置缓存中的条目。

    cmake -D var:type=value

    ,只是

    cmake -D var=value

    或与

    cmake -C CMakeInitialCache.cmake.

  • 缓存中的条目

    unset(... CACHE).

缓存是全局的,您可以在CMake脚本中的任何地方设置它们。但是,我建议您仔细考虑在哪里使用缓存变量(它们是全局的,它们是持久的)。我通常更喜欢set_property(GLOBAL PROPERTY ...)set_property(GLOBAL APPEND PROPERTY ...)语法来定义我自己的非持久性全局变量。

变量陷阱和“如何调试变量更改?”

为了避免陷阱,您应该了解以下有关变量的知识:

  • 如果局部变量具有相同的名称,则会隐藏缓存的变量。
  • 这个

    find_...

    命令-如果成功-将其结果写入缓存变量,“以便没有调用再次搜索”。
  • CMake中的列表只是带有分号分隔符的字符串。

    因此,引号很重要。
    • set(MyVar a b c)

      "a;b;c"

      set(MyVar "a b c")

      "a b c"

    • 建议是,当您希望将列表作为列表时,始终使用引号作为例外。
    • 一般倾向于

      list()

      处理列表的命令
  • 上述整个范围问题。特别是推荐使用

    functions()

    而不是

    macros()

    因为您不希望您的局部变量出现在父作用域中。
  • 属性设置了许多CMake使用的变量。

    project()

    enable_language()

    因此,在使用这些命令之前设置一些变量可能变得非常重要。
  • 环境变量可能与CMake生成make环境和使用make文件的位置不同。
    • 环境变量中的更改不会重新触发生成过程.
    • 特别是生成的IDE环境可能与命令行不同,因此建议将环境变量转换为缓存的内容。

有时,只有调试变量才有帮助。以下几点可能对你有帮助:

  • 简单地使用旧的

    printf

    使用

    message()

    命令。还有一些可以使用CMake本身附带的模块:

    CMakePrintHelpers.cmakeCMakePrintSystemInforma.cmake

  • 调查

    CMakeCache.txt

    文件在二进制输出目录中。如果make环境的实际生成失败,甚至会生成此文件。
  • 使用

    可变表()

    查看变量的读取/写入/删除位置。
  • 查看目录属性

    缓存变量

    变量

  • cmake追踪

    cmake --trace ...

    查看CMake的完整解析过程。这是最后一个储备,因为它产生了大量的产出。

特殊语法

  • 环境变量
    • 你能读懂

      $ENV{...}

      set(ENV{...} ...)

      环境变量
  • 生成器表达式
    • 生成器表达式

      $<...>

      只有在CMake的生成器编写make环境时(它与解析器替换为“就地”的普通变量进行比较时,才会对其进行评估。)
    • 非常方便,例如在编译器/链接器命令行和多配置环境中。
  • 参考文献
    • 带着

      ${${...}}

      您可以在变量中指定变量名并引用其内容。
    • 常用于将变量名命名为函数/宏参数时使用。
  • 常量值(见

    if()

    命令)
    • 带着

      if(MyVariable)

      您可以直接检查变量是否为true/false(这里不需要将其括起来)。

      ${...})

    • 如果常数是

      1ONYESTRUEY

      或者一个非零的数字。
    • 如果常量为

      0OFFNOFALSENIGNORENOTFOUND

      ,空字符串,或以后缀结尾。

      -NOTFOUND.

    • 此语法通常用于以下内容:

      if(MSVC)

      ,但对于不知道此语法快捷方式的人来说,这可能会让人感到困惑。
  • 递归替换
    • if("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")

      为true,因为它的计算值为

      if("1" STREQUAL "1")

    • if(CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")

      为false,因为它的计算值为

      if("MSVC" STREQUAL "1")

    • 所以这里最好的解决方案是直接检查

      if(MSVC)

    • 可以使用变量构造变量名。在CMake替换了变量之后,它将再次检查结果本身是否是变量。这是CMake本身使用的非常强大的特性,例如作为模板

      set(CMAKE_${lang}_COMPILER ...)

    • 注意

      这会让你头疼

      if()

      命令。下面是一个例子

      CMAKE_CXX_COMPILER_ID

      "MSVC"

      MSVC

      "1":

    • 好消息是,在CMake 3.1中,随着

      政策CMP 0054

      ..我建议你总是

      cmake_policy(SET CMP0054 NEW)

      “只解释”

      if()

      在未引用时,参数作为变量或关键字。“
  • 这个

    option()

    命令
    • 主要是缓存字符串,这些字符串只能

      ON

      OFF

      他们允许一些特殊的处理,如。

      相依性

    • 注意

      ,不要弄错

      option

      带着

      set

      命令。给予的价值

      option

      实际上仅仅是“初始值”(在第一个配置步骤中只传输到缓存一次),然后由用户通过

      CMake图形用户界面.

参考文献

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值