您遇到了 CMake 的一个相当烦人的“这不是错误,而是一个特性”行为。如if 命令的文档中所述:
The if command was written very early in CMake's history, predating the ${}
variable evaluation syntax, and for convenience evaluates variables named
by its arguments as shown in the above signatures.
好吧,便利变成了不便。在您的示例中,字符串"d"被视为d由if命令命名的变量。如果变量d恰好被定义为空字符串,则消息语句将打印“oops...”,例如:
set (d "")
if("d" STREQUAL "")
# this branch will be taken
message("oops...")
else()
message("fine")
endif()
这可以为以下语句提供令人惊讶的结果
if("${A}" STREQUAL "some string")
因为如果变量A恰好被定义为一个字符串,该字符串也是一个 CMake 变量的名称,例如:
set (A "d")
set (d "some string")
if("${A}" STREQUAL "some string")
# this branch will be taken
message("oops...")
else()
message("fine")
endif()
可能的解决方法:
您可以在展开后向字符串添加后缀字符,以${}防止 if 语句进行自动评估:
set (A "d")
set (d "some string")
if("${A} " STREQUAL "some string ")
message("oops...")
else()
# this branch will be taken
message("fine")
endif()
不要使用${}扩展:
set (A "d")
set (d "some string")
if(A STREQUAL "some string")
message("oops...")
else()
# this branch will be taken
message("fine")
endif()
为了防止在右侧STREQUAL使用CMake 正则表达式MATCHES进行意外评估:
if(A MATCHES "^value$")
...
endif()
附录:CMake 3.1 不再对引用的参数进行双重扩展。请参阅新政策。