Cygwin 的 cmake 与 CMAKE_SYSTEM_NAME 不匹配

joe*_*tde 5 c++ regex cygwin cmake match

我在使用 cmake 的 cygwin 上有一个奇怪的行为。我尝试检查 CMakeLists.txt 中的操作系统,但似乎这种特殊情况不起作用...这是一个引发我的问题的示例:

set (FOO "BAR")

message(${CMAKE_SYSTEM_NAME})

if (${CMAKE_SYSTEM_NAME} STREQUAL "CYGWIN")
    message("EQUALS CYGWIN")
endif()

if (${CMAKE_SYSTEM_NAME} MATCHES "CYGWIN")
    message("MATCHES CYGWIN")
endif()

if (${FOO} MATCHES "BAR")
    message("MATCHES BAR")
endif()
Run Code Online (Sandbox Code Playgroud)

CMake 打印:

CYGWIN
EQUALS CYGWIN
MATCHES BAR
Run Code Online (Sandbox Code Playgroud)

而不是预期的“MATCHES CYGWIN”。我觉得很奇怪,它适用于其他变量(比如这里的 FOO)。我做错了什么吗?

配置:

  • cmake 版本 2.8.11.2
  • 命名 CYGWIN_NT-6.1

PS:我还检查了 FOO =“CYGWIN”,两者都不匹配。似乎这个特定的字符串不适用于 MATCHES...

小智 4

原因

cmake 命令的签名if

if(<variable|string> MATCHES regex)
Run Code Online (Sandbox Code Playgroud)

但不是

if(<string> MATCHES regex)
Run Code Online (Sandbox Code Playgroud)

这意味着首先检查变量 ,如果没有这样的变量,则使用字符串CYGWINCYGWIN

证明

只需尝试打印CYGWIN变量(请参阅文档):

> cat CMakeLists.txt
cmake_minimum_required(VERSION 2.8.12)
project(foo)
message("cygwin variable: ${CYGWIN}")
> cmake -H. -B_builds
...
cygwin variable: 1
...
Run Code Online (Sandbox Code Playgroud)

详细的

if (${CMAKE_SYSTEM_NAME} STREQUAL "CYGWIN")
    # variable CYGWIN vs variable CYGWIN, i.e. 1 == 1
    message("EQUALS CYGWIN") # success
endif()

if (${CMAKE_SYSTEM_NAME} MATCHES "CYGWIN")
    # variable CYGWIN (i.e. 1) vs regex CYGWIN
    message("MATCHES CYGWIN") # fail
endif()

if (${FOO} MATCHES "BAR")
    # string BAR vs string BAR
    message("MATCHES BAR") # success
endif()
Run Code Online (Sandbox Code Playgroud)

解毒剂

<variable|string>尽可能 避免使用带签名的命令,因为任何名称都可以应用于变量:

> cat CMakeLists.txt
cmake_minimum_required(VERSION 2.8.12)
project(foo)
set("/this/is/definitely/not/a/variable/name" "surprise!")
message("${/this/is/definitely/not/a/variable/name}")
> cmake -H. -B_builds
...
surprise!
...
Run Code Online (Sandbox Code Playgroud)

例如,您可以使用字符串命令:

string(COMPARE EQUAL "${CMAKE_SYSTEM_NAME}" "CYGWIN" is_cygwin)
if(is_cygwin)
  message("Hello, cygwin!")
endif()
Run Code Online (Sandbox Code Playgroud)

请注意,在您的特定情况下,您可以简单地使用CYGWIN变量检查:

if(CYGWIN)
  message("Hello, cygwin!")
endif()
Run Code Online (Sandbox Code Playgroud)

有关的