2014-09-12 207 views
15

我想知道爲什麼經常在CMake中的變量被美元符號和大括號包裹。例如,我看到這個電話in a CMake tutorial

include_directories(${PROJECT_BINARY_DIR}) 

但是從我所嘗試的,這是做同樣的事情。

include_directories(PROJECT_BINARY_DIR) 

什麼時候需要打包${...},這是什麼意思?爲什麼變量經常包含這個,即使它沒有區別?

回答

14

引用the CMake documentation

可變參考的形式${variable_name}和評價 一個引用參數或無報價參數內。變量參考 被替換爲變量的值,或者如果未設置該變量,則通過空字符串取代 。

換句話說,編寫PROJECT_BINARY_DIR字面上指字符串「PROJECT_BINARY_DIR」。封裝在${...}中給你變量名稱爲PROJECT_BINARY_DIR的內容

考慮:

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

正如你可能已經猜到了已經,include_directories(PROJECT_BINARY_DIR)只是試圖名字PROJECT_BINARY_DIR的子目錄添加到include目錄。在大多數構建系統中,如果不存在這樣的目錄,則它將簡單地忽略該命令,這可能已經誘使您認爲它按預期工作。

混亂的流行源來自一個事實,即if()不需要的變量明確的反引用:

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

再次the documentation explains this behavior

if(<constant>)

真要是常數1 ,ON,YES,TRUE,Y或非零數字。如果常量爲0,OFF,NO,FALSE,N,IGNORE,NOTFOUND, 空字符串,或者以後綴-NOTFOUND結尾,則爲False。命名布爾常量 不區分大小寫。如果參數不是這些常量中的一個,則它被視爲一個變量。

if(<variable>)

如果變量被定義爲不是錯誤的恆定的值

真。否則爲假。 (注意宏參數不是變量。)

特別地,人們可以想出像怪異的例子:

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

將於在可變的情況下TRUE分支,並在恆定的情況下FALSE分支。這是因爲在常量情況下,CMake會尋找一個變量BLA來執行檢查(這是沒有定義的,因此我們最終在FALSE分支中)。

+0

那麼像if(SFML_FOUND)'這樣的工作如何呢? – danijar 2014-09-12 13:43:13

+2

'if()'是一個特例,因爲它對變量和值都起作用。雖然'if(SFML_FOUND)'和'if($ {SFML_FOUND})'可以同時工作,但它們實際上做了不同的事情:檢查[if']的文檔(http://www.cmake.org/cmake/help /v3.0/command/if.html),並特別注意'if()'和'if()'之間的區別。我會相應地更新答案。 – ComicSansMS 2014-09-12 13:45:56

相關問題