【问题标题】:How to specify the variable which must be set and exist in cmake如何指定cmake中必须设置和存在的变量
【发布时间】:2016-09-21 09:43:40
【问题描述】:

我需要指定一些变量并存在于环境中。 如果它不存在需要停止构建。

例子

if ( "${VARMUSTEXIST}" STREQUAL "ON" )
   message(STATUS is ON)
elif ("${VARMUSTEXIST}" STREQUAL "OFF")
   message(STATUS is OFF)
endif()

我不想在脚本的任何地方都添加if (defined VARMUSTEXIST)。 在 bash 中有一个“set -u”选项。

【问题讨论】:

  • 取消引用时,CMake 将所有未定义的变量视为具有空值。据我所知,没有办法影响这种行为。顺便说一句,如果没有定义变量,简单的if(VARMUSTEXIST) 将被视为false。相同的条件可用于在“ON”和“OFF”之间进行选择 - 这些字符串对于if 命令具有特殊含义。

标签: variables cmake defined


【解决方案1】:

一些初步的观点:

  • if ( "${VARMUSTEXIST}" STREQUAL "ON" ) [...] elif(AGAIN LONG EXPRESSION) [...] endif()
    通常在cmake中很简单:
    if (VARMUSTEXIST) [...] else() [...] endif()
  • 命令if (DEFINED VARMUSTEXIST) 要求DEFINED 为大写。
  • 您提到了 bash 和环境变量:
    使用 $ENV{VARIABLE_NAME} 读取环境变量
  • 对于环境变量你会做:

    if(NOT DEFINED ENV{VARMUSTEXIST})
        message(FATAL_ERROR "You must set VARMUSTEXIST environment variable")
    endif()
    

你说:

我不想在脚本的任何地方都添加if (defined VARMUSTEXIST)

我不清楚:对于每个变量,您只需要检查一次,可能在主 CMakeLists.txt 中。当然需要加NOT:if (NOT DEFINED VARMUSTEXIST) [stop]

如果您可以更准确地解决您的问题,我们可以设计一个宏来检查是否定义了一个或一组变量。

【讨论】:

  • 在 cmake 脚本开头有一个宏来检查变量列表的想法确实很好,但它无法捕捉到开发人员犯错并拼错变量名的情况。 Cmake 将默默地继续。我想做的是告诉cmake,在读取变量的值时,它应该始终检查变量是否已定义,如果未定义则失败。为了兼容性,必须为当前的 cmake 文件启用此选项,否则将无法包含现有的 cmake 文件而不破坏它们。
  • 至于bash,我只提到它是因为强制所有变量都必须定义的特性。例如,以下 bash 脚本将导致错误:#!/bin/bashset -uVAR=Yecho ${VA} 有可能编写如下内容会很酷:cmake_policy (SET READ_UNDEFINED_VARIABLES OFF)message (STATUS ${VA}) 现在消息行将失败.在使用之前,仍然可以使用if (DEFINED VA) 来检查它是否存在。
  • @D.Alex 关于开发人员拼写错误的风险,几年前提出了完全相同的问题,请参阅here。不幸的是,没有解决方法。也许您想发出功能请求(请注意,即使在 C 语言中也有 workaround)。顺便说一句,为了向后兼容而引入的策略不适合此目的。见doc
【解决方案2】:

如果你所说的环境是指操作系统环境变量,那么无论如何语法都是错误的。

如果这些是用户提供的选项,那么与 ON 和 OFF 的字面比较不正确,因为 CMake 有更多的方式来表达布尔值,并且它们都被广泛使用并成为惯用的.因此,通过期待ONOFF,您正在使您的构建脚本变得怪异并且违背每个人的期望。正如您所注意到的,您还为自己做更多的工作。

首先,您应该记录选项并使用option() 为它们提供安全的默认值。那么就永远不会有未定义的变量。

# early in the top-level CMakeLists.txt
option(VARMUSTEXIST "You can provide it. It exists anyway." NO)

然后你会很简单地检查它的真假:

# later in top-level file or in subdirectories
if (VARMUSTEXIST)
   message("VARMUSTEXIST is true")
else()
   message("VARMUSTEXIST is false")
endif()

【讨论】:

    【解决方案3】:

    我认为这是最好的方法...

    CMake 变量:

    if(NOT DEFINED VARIABLE)
        message(FATAL_ERROR "VARIABLE is not set")
    endif(NOT DEFINED VARIABLE)
    

    环境变量:

    if(NOT DEFINED ENV{VARIABLE})
        message(FATAL_ERROR "VARIABLE is not set")
    endif(NOT DEFINED ENV{VARIABLE})
    

    【讨论】:

      猜你喜欢
      • 2016-04-25
      • 1970-01-01
      • 2023-03-11
      • 1970-01-01
      • 2015-10-16
      • 2022-07-19
      • 2015-01-26
      • 2017-03-09
      • 1970-01-01
      相关资源
      最近更新 更多