2014-09-12 4 views
15

Ich frage mich, warum oft Variablen in CMake mit einem Dollarzeichen und geschweiften Klammern umwickelt sind. Zum Beispiel sah ich diesen Anruf in a CMake tutorial.

include_directories(${PROJECT_BINARY_DIR}) 

Aber von dem, was ich versuchte, tut dies das Gleiche.

include_directories(PROJECT_BINARY_DIR) 

Wenn die Verpackung mit ${...} benötigt und was bedeutet es? Warum werden Variablen oft damit umschlossen, auch wenn es keinen Unterschied macht?

Antwort

14

the CMake documentation Zitiert:

A variable Referenz hat die Form ${variable_name} und innerhalb eines Zitiert Argument oder ein Unquoted Argument ausgewertet. Eine Variablenreferenz wird durch den Wert der Variablen oder durch die leere Zeichenfolge ersetzt, wenn die Variable nicht festgelegt ist.

Mit anderen Worten, das Schreiben PROJECT_BINARY_DIR bezieht sich wörtlich auf die Zeichenfolge "PROJECT_BINARY_DIR". Wenn Sie es in ${...} einkapseln, erhalten Sie den Inhalt der Variablen mit dem Namen PROJECT_BINARY_DIR.

Bedenken Sie:

set(FOO "Hello there!") 
message(FOO)  # prints FOO 
message(${FOO}) # prints Hello there! 

Wie Sie wahrscheinlich schon erraten haben, include_directories(PROJECT_BINARY_DIR) versucht einfach ein Unterverzeichnis des Namens PROJECT_BINARY_DIR zu den Include-Verzeichnisse hinzuzufügen. Wenn auf den meisten Build-Systemen kein solches Verzeichnis existiert, ignoriert es einfach den Befehl, der Sie möglicherweise in die Impression hineingelockt hat, dass es wie erwartet funktioniert.

Eine beliebte Quelle der Verwirrung kommt von der Tatsache, dass if() nicht explizit dereferenzierenden von Variablen benötigt:

set(FOO TRUE) 
if(FOO) 
    message("Foo was set!") 
endif() 

Wieder the documentation explains this behavior:

if(<constant>)

Wahr, wenn die Konstante 1 ist , EIN, JA, WAHR, Y oder eine von Null verschiedene Zahl. False, wenn die Konstante 0 ist, OFF, NO, FALSE, N, IGNORE, NOTFOUND, die leere Zeichenfolge oder endet im Suffix -NOTFOUND. Benannte boolesche Konstanten sind case-insensitive. Wenn das Argument nicht eine dieser Konstanten ist, wird als eine Variable behandelt.

if(<variable>)

Wahr, wenn der Variable auf einen Wert festgelegt ist, die nicht eine falsche Konstante ist. Falsch sonst. (Hinweis: Makroargumente sind keine Variablen.

)

Insbesondere kann man mit seltsamen Beispielen kommen wie:

unset(BLA) 
set(FOO "BLA") 
if(FOO) 
    message("if(<variable>): True") 
else() 
    message("if(<variable>): False") 
endif() 
if(${FOO}) 
    message("if(<constant>): True") 
else() 
    message("if(<constant>): False") 
endif() 

, die den TRUE Zweig in dem Variablen Fall nehmen, und den FALSE Zweig im konstanten Fall. Dies liegt daran, dass CMake im konstanten Fall nach einer Variablen BLA sucht, um die Überprüfung durchzuführen (was nicht definiert ist, daher landen wir im FALSE-Zweig).

+0

Wie funktioniert dann etwas wie 'if (SFML_FOUND)'? – danijar

+2

'if()' ist ein Sonderfall, da er sowohl für Variablen als auch für Werte funktioniert. Während 'if (SFML_FOUND)' und 'if ($ {SFML_FOUND}) 'beide funktionieren könnten, machen sie tatsächlich verschiedene Dinge: Prüfe [die Dokumentation für' if'] (http://www.cmake.org/cmake/help) /v3.0/command/if.html) und besonders auf den Unterschied zwischen "if ()" und "if ()" achten. Ich werde die Antwort entsprechend aktualisieren. – ComicSansMS

Verwandte Themen