cmake預定義變數和執行流程控制

2021-08-24 21:27:49 字數 3742 閱讀 2346

《你所不知的osg》第一章:cmake初步(2) - openscenegraph教程專區 - openscenegraph中國討論區-有您osg在中國才更好 - powered by discuz!

也許您並不一定完全明白這裡所說的每一句話,這也是我們之所以把詞法和語法的介紹放在「hello world」例子之後的乙個原因——沒錯,僅僅是這些單詞的羅列未免太枯燥了。那麼,為什麼不馬上拾起我們剛剛才完成的簡單指令碼工程,在上面添磚加瓦一番呢?說不定這才是您充分理解和深入學習cmake的關鍵呢。

是的,實踐才是最好的老師。要充分理解cmake的強大之處,以及確保自己具備足夠的力量去閱讀osg的cmake指令碼源**,勢必還要再多做一些更為複雜的練習才行。不過在此之前,我們還是再多了解一些cmake的常用內建變數和指令碼命令,以及cmake中條件語句,迴圈語句和巨集函式的概念用法。

包括前文介紹的project_source_dir在內,以下內建全域性變數都可以在cmake指令碼中以「$」的形式直接加以應用,以方便指令碼**的定位和功能實現:

* cmake_build_type:工程的編譯生成的版本型別,可選項包括debug,release,relwithdebinfo和minsizerel。

* cmake_command:也就是cmake可執行檔案本身的全路徑,例如/usr/local/bin/cmake或者c:\program files\cmake 2.6\bin\cmake.exe。

* cmake_debug_postfix:debug版本生成目標的字尾,通常可以設定為「d」字元,例如debug版本的osg核心庫為osgd.dll,而release版為osg.dll。

* cmake_generator:編譯器名稱,例如「unix makefiles」,「visual studio 7」等。

* cmake_install_prefix:工程安裝目錄,所有生成和呼叫所需的可執行程式,庫檔案,標頭檔案都會安裝到該路徑下,unix/linux下預設為/usr/local,windows下預設為c:\program files。

* cmake_module_path:設定搜尋cmakemodules模組(.cmake)的額外路徑。

* project_binary_dir:工程生成工作所在的目錄,即前文所述的「out-of-source」的目錄;對於「in-source」形式的編譯工作,該變數與project_source_dir所指向的目錄相同。

* project_name:工程名稱,即使用project命令設定的名稱。

* project_source_dir:工程源**檔案所在的目錄。

* cygwin:標識當前系統是否為cygwin。

* msvc:標識當前系統是否使用microsoft visual c。

* win32:標識當前系統是否為windows及win64。

不必擔心這裡介紹的命令和變數太多,也不必擔心它們會很快消失在您的腦海深處。下一節我們將嘗試建立乙個稍微複雜一些的工程versionme,並爭取將上文涉及到的大部分命令和內建變數派上用場,以求在實戰中讓您領略到cmake的強大魅力。

不過在結束枯燥的本章之前,我們還需要介紹一下cmake中重要的條件語句語法,迴圈語句語法和巨集函式。它們分別相當於c程式中的if…else,while/for以及函式的作用,並且條件和迴圈語句都可以巢狀工作。毫無疑問,它們在指令碼語言的流程控制過程中必然不可或缺。

cmake中的條件語句基本格式為:

1. if( expression )

2. …

3. else( expression )

4. …

5. endif( expression )

複製**

或者,1. if( expression1 )

2. …

3. elseif( expression2 )

4. …

5. else()

6. …

7. endif()

複製**

這裡的expression是判斷條件,和c/c++類似,cmake的條件也存在「與/或/非」以及「等於/大於/小於」等幾種操作符,分別用and/or/not以及equal/less/greater來表示。當判斷條件為真,執行if後的命令段,否則繼續判斷並執行相應條件對應的命令段,或者不執行任何操作。例如:

1. if ( $ greater 4 )

2. …

3. endif( $greater 4 )

複製**

表示判斷變數number是否大於4,進而執行對應的語句段。此時使用者定義的字串變數會被自動轉換為整型變數以便進行判斷。

此外形同這樣的判斷語句也是十分常見的:

1. if ( not $ )

2. …

3. endif( not $ )

複製**

如果變數variable的值為空,0,n,no,off,false,notfound這幾種之一的話,則認為此變數表示「假」,即此處的「not $」為真。

cmake中的迴圈語句基本格式為:

1. foreach( var arg1 arg2 … )

2. …

3. endforeach( var )

複製**

這裡設定乙個迴圈的區域性變數var,每次將其賦為arg1,arg2等變數(或者變數陣列)中的乙個值,並執行迴圈中的命令段。例如:

foreach( var $ ),它表示將區域性變數var每次設定為變數opengl_libraries中的乙個值。後者的內容可能為「opengl32.lib;glu32.lib」的形式。

cmake自動將分號分隔的字串認為是陣列,因此會自動從該變數中擇取var的取值。

另一種表達迴圈語句的語法格式為:

1. while ( expression )

2. …

3. endwhile( expression )

複製**

這裡的expression和if語句判斷欄位中的含義相同。

cmake中的巨集函式可以理解為c語言的函式,它改變**執行跳轉的流程並簡化了指令碼程式的開發,其基本格式為:

1. macro( funcname [arg1 [arg2 …]] )

2. …

3. endmacro( funcname )

複製**

和函式的編寫要求一樣,cmake的巨集函式必須指定乙個函式名funcname,以及零個或多個輸入引數arg1,arg2等。需要呼叫巨集函式的時候,只要直接使用funcname(arg1 arg2)的形式就可以了,例如:

1. macro( my_func arg1 arg2 )

2. …

3. endmacro( my_func )

複製**

在主程式中,需要呼叫此巨集函式時,只需執行形同下面的語句:

1. myfunc( param1 param2 )

複製**

就可以將實際引數param1和param2傳入巨集函式體。

此外,巨集函式體內可以使用內建變數$,$和$來表達傳入引數的屬性:$儲存了傳入引數的個數;$儲存乙個傳入引數組成的陣列,可以供foreach語句使用;$則比較特殊,它儲存了「顯式引數」之外的所有「隱式引數」所組成的陣列。對於上面的例句來說,arg1,arg2就是顯式引數,而如果使用者在呼叫my_func時採用下面的形式:

1. myfunc( param1 param2 other1 other2 … )

複製**

那麼other1,other2等就是隱式引數,可以用$來獲取它們的陣列。這對於cmake而言是完全合法的,並且可以因此定義不定引數項的巨集函式,從而大大增強了指令碼程式的靈活性。

CMake常用的預定義變數

project name 通過 project 指定專案名稱 project source dir 工程的根目錄 project binary dir 執行 cmake 命令的目錄 cmake current source dir 當前 cmakelist.txt 檔案所在的目錄 cmake cur...

CMake中常用的預定義變數

project name 通過project指定的專案名稱 project demo project source dir 工程的根目錄,上圖中的demo目錄 project binary dir 執行cmake命令的目錄,一般是在build目錄,在此目錄執行cmake cmake current ...

預定義變數

不包含副檔名的目標檔名稱。所有的依賴檔案,以空格分開,並以出現的先後為序,可能包含重複的依賴檔案。第乙個依賴檔案的名稱。所有的依賴檔案,以空格分開,這些依賴檔案的修改日期比目標的建立日期晚。目標的完整名稱。所有的依賴檔案,以空格分開,不包含重複的依賴檔案。如果目標是歸檔成員,則該 變數表示目標的歸檔...