44

2 つの文字列 (変数ではなく) を比較したい場合は、次のように引用するだけでよいと常に考えています。

if("${A}" STREQUAL "some string")

しかし今、このコードが時々出力されることがわかりましたoops

cmake_minimum_required(VERSION 2.8)

if("d" STREQUAL "")
  message("oops...")
endif()

バグかもしれません ( Xcodeでは出力されますが、 makeでは出力されないため)? または、いくつかの特別な変数がありますか?

  • cmake: 2.8.12、2.8.11.2
  • クロスコード: 4.6.2、5.0.1

アップデート

問題が説明されていないコマンド文字列があります。

string(COMPARE EQUAL "${A}" "" result)
if(result)
  message("...")
endif()

更新 2

CMake 3.1.0以降に実装されると予想される動作( CMP0054を参照)。

3.0.2テストの出力:

CMake version: 3.0.2
Quoted test
Surprise!
Unquoted test
Surprise!

3.1.0テストの出力:

CMake version: 3.1.0
Quoted test
OK
Unquoted test
Surprise!
4

2 に答える 2

56

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"付けられた変数として扱われます。変数がたまたま空の文字列に定義されている場合、メッセージ ステートメントは「oops...」を出力します。次に例を示します。difd

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()

代わりにCMake 正規表現STREQUALを使用MATCHESして、使用の右側で意図しない評価を防ぐには:

if(A MATCHES "^value$")
  ...
endif()

補遺: CMake 3.1 は、引用符で囲まれた引数の二重展開を行わなくなりました。新しいポリシーを参照してください。

于 2013-11-14T21:33:37.670 に答える