【问题标题】:cmake: how to check if preprocessor is definedcmake:如何检查是否定义了预处理器
【发布时间】:2017-09-14 02:06:55
【问题描述】:

我无法让cmake 测试是否已定义预处理器。例如:

cmake_minimum_required(VERSION 2.8.9)
project (cmake-test)
add_definitions(-DOS=LINUX)

if(NOT <what condition goes here?>)
    message(FATAL_ERROR "OS is not defined")
endif()

以下测试不起作用:

if (NOT COMMAND OS)
if (NOT DEFINED OS)
if (NOT OS)

我可以通过使用set() 并仅测试常规cmake 变量然后定义预处理器宏来使其工作。例如:

set(OS LINUX)
if (OS)
    add_definitions(-DOS=${OS})
else()
    message(FATAL_ERROR "OS is not defined")
endif()

如果您想知道如果变量/预处理器在 same 文件中,为什么我需要对其进行测试,这是因为在最终实现中,这些将来自外部文件,即 @ 987654328@ed 在主 CMakeFile.txt 例如:

include(project_defs.txt)
if (OS)
    ....

【问题讨论】:

  • 预处理器是什么意思? CMake 没有...
  • CMake 自动定义了几个变量来描述系统。因此,您可以检查(在if 命令中)这些变量是否包含依赖于操作系统的代码。见Variables That Provide Information
  • @usr1234567 by pre-processor 我的意思是由-D选项定义的变量gcc(与#define相同)。
  • @Tsyvarev OS 只是一个例子。我要定义的是我的项目的自定义属性,所以cmake 不会知道它们。
  • 那么,您的方法有什么问题(设置 CMake 变量,然后检查它)?如果 cmake 脚本被包含(通过include() 命令),那么调用者可以看到它的所有定义。 (他们说,that include() 没有引入变量定义范围)。

标签: cmake preprocessor


【解决方案1】:

这是用箭头完成答案。

我还尝试了上面箭头所指的 COMPILE_DEFINITIONS 选项,但未成功。

按照 CMake 的文档,至少对于 3.x 版本,事实证明,当您在 CMake 中调用 add_definitions() 时,它会将定义添加到 COMPILE_DEFINITIONS 目录强> 属性。

因此,假设您根据代码定义以下内容:

add_definitions(-DOS=LINUX)

要检索带有添加到变量“MYDEFS”中的定义的字符串,您可以在 CMake 中使用以下行:

get_directory_property(MYDEFS COMPILE_DEFINITIONS)
MESSAGE( STATUS "Compile defs contain: " ${MYDEFS} )

然后您可以检查${MYDEFS} 中您要查找的定义是否存在。比如

if(MYDEFS MATCHES "^OS=" OR MYDEFS MATCHES ";OS=")
    MESSAGE( STATUS "OS defined" )
else()
    # You can define your OS here if desired
endif()

【讨论】:

    【解决方案2】:

    通常,传递给编译器的所有定义都由 CMake 控制。也就是说,您使用

    创建一个 CMake 变量
    option(SOMEFEATURE "Feature description" ON)
    

    set(OS "" CACHE STRING "Select your OS")
    

    用户通过cmake -D OS=DOS 或在 CMake GUI 中设置它们。然后您可以使用if() 运算符有条件地add_definitions() 到编译器命令行。

    更新:

    如果你真的想访问预处理器标志,有一个COMPILE_DEFINITIONS 目标属性。您可以通过以下方式访问它:

    get_target_property(OUTVAR target COMPILE_DEFINITIONS)
    

    【讨论】:

    • 那么我提到的第二种方法可能是我想这样做的唯一方法。如果cmake 允许测试通过add_definitions 设置的东西会很好。
    • 感谢您的更新。我确实查看了COMPILE_DEFINITIONS 作为add_definitions() 的文档提到它。但是我无法获取指定的定义(我尝试了您使用 get_target_property 的建议,但得到了 NOTFOUND 代替)。我正在使用cmake 2.8.12.2
    • 这很奇怪,因为即使是 2.8 也存在这样的属性:cmake.org/cmake/help/v2.8.12/… 尝试使用更新的 CMake。
    猜你喜欢
    • 2013-06-18
    • 2011-08-16
    • 2011-04-08
    • 2012-02-19
    • 2020-03-16
    • 1970-01-01
    • 1970-01-01
    • 2019-08-27
    相关资源
    最近更新 更多