(8)CMake入門筆記--CMake語法

參考地址:

https://www.cnblogs.com/binbinjx/p/5626916.html
https://blog.csdn.net/ajianyingxiaoqinghan/article/details/70230902

感謝以上兩位分享

前提

1、每一個需要進行cmake操作的目錄下面,都必須存在文件CMakeLists.txt 。

2、cmake指令不區分大小寫。本文爲了醒目,筆者把cmake指令都作大寫處理。

3、變量使用${}方式取值,但是在 IF 控制語句中是直接使用變量名;

4、指令(參數 1 參數 2…),參數使用括弧括起,參數之間使用空格或分號分開;

一. CMake中常用預定義變量

1. CMake的預定義變量

PROJECT_SOURCE_DIR:工程根目錄;

PROJECT_BINARY_DIR:運行cmake命令的目錄;

CMAKE_INCLUDE_PATH:; -list指定find_file()和find_path()命令的搜索路徑的目錄。 默認情況下它是空的,它由項目設置。 另請參見CMAKE_SYSTEM_INCLUDE_PATH和CMAKE_PREFIX_PATH。

CMAKE_LIBRARY_PATH:; -list指定find_library()命令的搜索路徑的目錄。 默認情況下它是空的,它由項目設置。 另請參見CMAKE_SYSTEM_LIBRARY_PATH和CMAKE_PREFIX_PATH。

CMAKE_CURRENT_SOURCE_DIR:當前處理的CMakeLists.txt文件所在路徑;

CMAKE_CURRENT_BINARY_DIR:target編譯目錄;

使用ADD_SURDIRECTORY指令可以更改該變量的值;

SET(EXECUTABLE_OUTPUT_PATH < dir >) 指令不會對該變量有影響,但改變了最終目標文件的存儲路徑;

CMAKE_CURRENT_LIST_FILE:輸出調用該變量的CMakeLists.txt的完整路徑;

CMAKE_CURRENT_LIST_LINE:輸出該變量所在的行;

CMAKE_MODULE_PATH:定義自己的cmake模塊所在路徑;

EXECUTABLE_OUTPUT_PATH:重新定義目標二進制可執行文件的存放位置;

LIBRARY_OUTPUT_PATH:重新定義目標鏈接庫文件的存放位置;

PROJECT_NAME:返回由PROJECT指令定義的項目名稱;

2. 系統信息預定義變量

CMAKE_MAJOR_VERSION cmake主版本號,如2.8.6中的2

CMAKE_MINOR_VERSION cmake次版本號,如2.8.6中的8

CMAKE_PATCH_VERSION cmake補丁等級,如2.8.6中的6

CMAKE_SYSTEM 系統名稱,例如Linux-2.6.22

CMAKE_SYSTEM_NAME 不包含版本的系統名,如Linux

CMAKE_SYSTEM_VERSION 系統版本,如2.6.22

CMAKE_SYSTEM_PROCESSOR 處理器名稱,如i686

UNIX 在所有的類UNIX平臺爲TRUE,包括OS X和cygwin

WIN32 在所有的win32平臺爲TRUE,包括cygwin

3. 開關選項

BUILD_SHARED_LIBS 控制默認的庫編譯方式。

注:如果未進行設置,使用ADD_LIBRARY時又沒有指定庫類型,默認編譯生成的庫都是靜態庫。

CMAKE_C_FLAGS 設置C編譯選項

CMAKE_CXX_FLAGS 設置C++編譯選項

二. CMake常用語法

1. CMAKE_MINIMUM_REQUIRED

該語句一般都可以放置在CMakeLists.txt的開頭,用於說明CMake最低版本要求。 
這行命令是可選的,我們可以不寫這句話,但在有些情況下,如果CMakeLists.txt文件中使用了一些高版本cmake特有的一些命令的時候,就需要加上這樣一行,提醒用戶升級到該版本之後再執行cmake。

cmake_minimum_required (VERSION 2.6)

上述例程指cmake的最低版本至少爲2.6。

2. PROJECT

格式:

project(<PROJECT-NAME> [<language-name>...])
project(<PROJECT-NAME>
        [VERSION <major>[.<minor>[.<patch>[.<tweak>]]]]
        [DESCRIPTION <project-description-string>]
        [HOMEPAGE_URL <url-string>]
        [LANGUAGES <language-name>...])


 name:工程名稱;
該指令一般置於CMakeLists.txt的開頭,設置項目的名稱,並將其存儲在變量PROJECT_NAME中。 從頂級CMakeLists.txt調用時,還會將項目名稱存儲在變量CMAKE_PROJECT_NAME中。
執行了該條指令之後,將會自動創建兩個變量:

PROJECT_SOURCE_DIR, <PROJECT-NAME>_SOURCE_DIR
PROJECT_BINARY_DIR, <PROJECT-NAME>_BINARY_DIR

< projectname >_BINARY_DIR:二進制文件保存路徑;
< projectname >_SOURCE_DIR:源代碼路徑;
參數:LANGUAGES <language-name>...
可選的。 也可以指定不帶LANGUAGES關鍵字的第一個短簽名。

選擇構建項目所需的編程語言。 支持的語言包括C,CXX(即C ++),CUDA,Fortran和ASM。 默認情況下,如果未給出語言選項,則啓用C和CXX。 指定語言NONE,或使用LANGUAGES關鍵字並列出無語言,以跳過啓用任何語言。

如果啓用ASM,請將其列在最後,以便CMake可以檢查其他語言(如C)的編譯器是否也適用於彙編。

project(CRNode)

執行了上一條指令,即定義了一個項目名稱CRNode,相應的會生成兩個變量:

CRNode_BINARY_DIR, CRNode_SOURCE_DIR。 
cmake中預定義了兩個變量:PROJECT_BINARY_DIR與PROJECT_SOURCE_DIR。 
在這個例子中: 

PROJECT_BINARY_DIR = CRNode_BINARY_DIR 
PROJECT_SOURCE_DIR = CRNode_SOURCE_DIR 

關於上面兩個變量是否相同的問題,涉及到編譯方法是內部編譯還是外部編譯。如果是內部編譯,則上面兩個變量相同;如果是外部編譯,則兩個變量不同。

此處對內部編譯與外部編譯做出介紹:

(1) 外部構建與內部構建

假設此時已經完成了CMakeLists.txt的編寫,在CMakeLists.txt所在目錄下,有兩種執行cmake的方法:

cmake ./
make

以及:

mkdir build
cd ./build
cmake ../
make

第一種方法是內部構建,第二種方法是外部構建。上述兩種方法中,最大不同在於cmake與make的工作路徑不同。 
內部構建方法中,cmake生成的中間文件和可執行文件都會存放在項目目錄中;外部構建方法中,中間文件與可執行文件都存放在build目錄中。 
建議使用外部構建方法。優點顯而易見:最大限度的保持了代碼目錄的整潔,生成、編譯與安裝是不同於項目目錄的其他目錄中,在外部構建方法下,PROJECT_SOURCE_DIR指向目錄與內部構建相同,爲CMakeLists.txt所在根目錄;而PROJECT_BINARY_DIR不同,它指向CMakeLists.txt所在根目錄下的build目錄。

3. SET

格式:

set(<variable> <value>... [PARENT_SCOPE])

例:

SET(CMAKE_INSTALL_PREFIX /usr/local)

該例程中,我們顯式的將CMAKE_INSTALL_PREFIX的值定義爲/usr/local,如此在外部構建情況下執行make install命令時,make會將生成的可執行文件拷貝到/usr/local/bin目錄下。 
當然,可執行文件的安裝路徑CMAKE_INSTALL_PREFIX也可以在執行cmake命令的時候指定,cmake參數如下:

cmake -DCMAKE_INSTALL_PREFIX=/usr ..

如果cmake參數和CMakeLists.txt文件中都不指定該值的話,則該值爲默認的/usr/local。

4. ADD_SUBDIRECTORY

格式:

ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL])

source_dir:源文件路徑;
[binary_dir]:中間二進制與目標二進制存放路徑;
[EXECLUDE_FROM_ALL]:將這個目錄從編譯過程中排除;
這個指令用於向當前工程添加存放源文件的子目錄,並可以指定中間二進制和目標二進制存放的位置。EXCLUDE_FROM_ALL 參數的含義是將這個目錄從編譯過程中排除。比如,工程有時候存在example,可能就需要工程構建完成後,再進入example目錄單獨進行構建。

5. INCLUDE_DIRECTORIES

格式:

include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 ...])

[AFTER|BEFORE]:追加標誌,指定控制追加或置前;默認情況下,追加當前頭文件搜索路徑的後面。 
注:如果路徑包含空格,可以使用雙引號將它括起來。
[SYSTEM]:編譯器將被告知這些目錄在某些平臺上被視爲系統包含目錄。 發信號通知此設置可能會產生諸如編譯器跳過警告之類的影響,或者這些固定安裝系統文件未在依賴項計算中考慮
dir1, …, dir n:添加的一系列頭文件搜索路徑;
向工程添加多個特定的頭文件搜索路徑,路徑之間用空格分隔。類似於gcc中的編譯參數-l,即指定編譯過程中編譯器搜索頭文件的路徑。當項目需要的頭文件不在系統默認的搜索路徑時,則指定該路徑。 

例:

INCLUDE_DIRECTORIES(/usr/include/thrift)

6. ADD_EXECUTABLE

格式:

add_executable(<name> [WIN32] [MACOSX_BUNDLE]
               [EXCLUDE_FROM_ALL]
               [source1] [source2 ...])

exename:可執行文件名
srcname:生成該可執行文件的源文件
該命令給出源文件名稱,並指出需要編譯出的可執行文件名。

例1:

ADD_EXECUTABLE(hello ${SRC_LIST})

上述例程說明SRC_LIST變量中的源文件,需要編譯出名爲hello的可執行文件。

例2:

SET(SRC_LIST main.cc
        rpc/CRNode.cpp 
        rpc/Schd_types.cpp 
        task/TaskExecutor.cpp
        task/TaskMoniter.cpp
        util/Const.cpp 
        util/Globals.cc
        )

ADD_EXECUTABLE(CRNode ${SRC_LIST})

該例程中,定義了該工程會生成一個名爲CRNode的可執行文件,所依賴的源文件是變量SRC_LIST定義的源文件列表。 
注:如果前文PROJECT()指令中定義的項目名稱也定義爲CRNode,也沒有什麼問題,兩者之間沒有任何關係。

7. ADD_LIBRARY

格式:

add_library(<name> [STATIC | SHARED | MODULE]
            [EXCLUDE_FROM_ALL]
            [source1] [source2 ...])

libname:庫文件名稱;
[SHARED|STATIC|MODULE]:生成庫文件類型(共享庫/靜態庫)
[EXCLUDE_FROM_ALL]:表示該庫不會被默認構建
source1, …, sourceN:生成庫所依賴的源文件
例:

ADD_LIBRARY(hello SHARED ${LIBHELLO_SRC})

8. FIND_LIBRARY

查找庫所在目錄
語法:
 

A short-hand signature is:

find_library (<VAR> name1 [path1 path2 ...])
The general signature is:

find_library (
          <VAR>
          name | NAMES name1 [name2 ...] [NAMES_PER_DIR]
          [HINTS path1 [path2 ... ENV var]]
          [PATHS path1 [path2 ... ENV var]]
          [PATH_SUFFIXES suffix1 [suffix2 ...]]
          [DOC "cache documentation string"]
          [NO_DEFAULT_PATH]
          [NO_CMAKE_ENVIRONMENT_PATH]
          [NO_CMAKE_PATH]
          [NO_SYSTEM_ENVIRONMENT_PATH]
          [NO_CMAKE_SYSTEM_PATH]
          [CMAKE_FIND_ROOT_PATH_BOTH |
           ONLY_CMAKE_FIND_ROOT_PATH |
           NO_CMAKE_FIND_ROOT_PATH]
         )

例子如下:

FIND_LIBRARY(RUNTIME_LIB rt /usr/lib  /usr/local/lib NO_DEFAULT_PATH)

cmake會在目錄中查找,如果所有目錄中都沒有,值RUNTIME_LIB就會被賦爲NO_DEFAULT_PATH

9. 變量EXECUTABLE_OUTPUT_PATH, LIBRARY_OUTPUT_PATH

EXECUTABLE_OUTPUT_PATH爲生成可執行文件路徑,LIBRARY_OUTPUT_PATH爲生成庫文件路徑。 
我們可以通過SET指令對其進行設置最終的目標二進制的位置,即最終生成的工程可執行文件與最終的共享庫,而不包含編譯生成的中間文件。 
命令如下:

SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)

注:指令ADD_EXECUTABLE, ADD_LIBRARY出現的位置,如果需要改變目標存放路徑,就在該處添加上述定義。
 

10. LINK_DIRECTORIES

格式:

link_directories([AFTER|BEFORE] directory1 [directory2 ...])

該指令用於添加外部庫的搜索路徑。
它相當於g++命令的-L選項的作用,也相當於環境變量中增加LD_LIBRARY_PATH的路徑的作用。
例:

link_directories("/home/server/third/lib")

11. LINK_LIBRARIES

添加需要鏈接的庫文件路徑

語法:

link_libraries([item1 [item2 [...]]]
               [[debug|optimized|general] <item>] ...)

例子:

# 直接是全路徑
link_libraries(“/home/server/third/lib/libcommon.a”)
# 下面的例子,只有庫名,cmake會自動去所包含的目錄搜索
link_libraries(iconv)

# 傳入變量
link_libraries(${RUNTIME_LIB})
# 也可以鏈接多個
link_libraries("/opt/MATLAB/R2012a/bin/glnxa64/libeng.so" "/opt/MATLAB/R2012a/bin/glnxa64/libmx.so")

可以鏈接一個,也可以多個,中間使用空格分隔.
 

12. TARGET_LINK_LIBRARIES

格式:

target_link_libraries(<target>
                      <PRIVATE|PUBLIC|INTERFACE> <item>...
                     [<PRIVATE|PUBLIC|INTERFACE> <item>...]...)

target:目標文件;
library1, …, libraryN:鏈接外部庫文件;
指定鏈接目標文件時需要鏈接的外部庫,效果類似於gcc編譯參數-L,解決外部庫依賴的問題。
# 以下寫法都可以: 

target_link_libraries(myProject comm)       # 連接libhello.so庫,默認優先鏈接動態庫
target_link_libraries(myProject libcomm.a)  # 顯示指定鏈接靜態庫
target_link_libraries(myProject libcomm.so) # 顯示指定鏈接動態庫

# 再如:

target_link_libraries(myProject libcomm.so)  #這些庫名寫法都可以。
target_link_libraries(myProject comm)
target_link_libraries(myProject -lcomm)

13. MESSAGE

向終端輸出用戶定義的信息或變量值; 
格式:

message([<mode>] "message to display" ...)

可選的<mode>關鍵字確定消息的類型:
FATAL_ERROR :CMake錯誤,停止處理和生成。
SEND_ERROR:產生錯誤,生成過程被跳過;
WARNING:CMake警告,繼續處理。
AUTHOR_WARNING:CMake警告(dev),繼續處理。
DEPRECATION:如果分別啓用了變量CMAKE_ERROR_DEPRECATED或CMAKE_WARN_DEPRECATED,則CMake Deprecation Error或Warning,否則無消息。
(none) or NOTICE:打印到stderr的重要信息吸引用戶注意。
STATUS:輸出前綴爲 – 的信息,項目用戶可能感興趣的主要有趣信息。理想情況下,這些信息應該簡潔,不超過一行,但仍然提供信息。
VERBOSE:針對項目用戶的詳細信息性消息。
DEBUG:針對項目本身的開發人員而非僅僅想要構建項目的用戶的詳細信息性消息。
TRACE:使用此日誌級別的消息通常只是臨時的,並且在發佈項目,打包文件等之前可能會被刪除。

14. SET_TARGET_PROPERTIES

設置目標的某些屬性,改變它們構建的方式。 
格式:

set_target_properties(target1 target2 ...
                      PROPERTIES prop1 value1
                      prop2 value2 ...)

該指令爲一個目標設置屬性,語法是列出所有用戶想要變更的文件,然後提供想要設置的值。用戶可以使用任何想用的屬性與對應的值,並在隨後的代碼中調用GET_TARGET_PROPERTY命令取出屬性的值。 
影響目標輸出文件的屬性PROPERTIES詳述如下:

(1) PREFIX, SUFFIX
PREFIX覆蓋了默認的目標名前綴(如lib); 
SUFFIX覆蓋了默認的目標名後綴(如.so)。

(2) IMPORT_PREFIX, IMPORT_PREFIX
與PREFIX, SUFFIX是等價的屬性,但針對的是DLL導入庫(即共享庫目標)。

(3) OUTPUT_NAME
構建目標時,OUTPUT_NAME用來設置目標的真實名稱。

(4) LINK_FLAGS
爲一個目標的鏈接階段添加額外標誌。 
LINK_FLAGS_< CONFIG >將爲配置< CONFIG >添加鏈接標誌,如DEBUG, RELEASE, MINSIZEREL, RELWITHDEBINFO。

(5) COMPILE_FLAGS
設置附加的編譯器標誌,在構建目標內的源文件時被用到。

(6) LINKER_LANGUAGE
改變鏈接可執行文件或共享庫的工具。默認值是設置與庫中文件相匹配的語言。 
CXX與C是該屬性的公共值。

(7) VERSION, SOVERSION
VERSION指定構建的版本號,SOVERSION指定構建的API版本號。 
構建或安裝時,如果平臺支持符號鏈接,且鏈接器支持so名稱,那麼恰當的符號鏈接將會被創建。如果只指定兩者中的一個,缺失的另一個假定爲具有相同版本號。 
例1:

SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello")

例2:

SET_TARGET_PROPERTIES(hello PROPERTEIES VERSION 1.2 SOVERSION 1)

該指令用於控制版本,VERSION指代動態庫版本,SOVERSION指代API版本。

15. AUX_SOURCE_DIRECTORY

查找某個路徑下的所有源文件,並將源文件列表存儲到一個變量中。 
格式:

AUX_SOURCE_DIRECTORY(< dir > < variable >)

例:

AUX_SOURCE_DIRECTORY(./src SRC_LIST)

該指令將當前目錄下的文件列表全部存入變量SRC_LIST中。

16. INSTALL

INSTALL命令可以按照對象的不同分爲三種類型:目標文件、非目標文件、目錄;

(1) 目標文件:
格式:

Installing Targets

install(TARGETS targets... [EXPORT <export-name>]
        [[ARCHIVE|LIBRARY|RUNTIME|OBJECTS|FRAMEWORK|BUNDLE|
          PRIVATE_HEADER|PUBLIC_HEADER|RESOURCE]
         [DESTINATION <dir>]
         [PERMISSIONS permissions...]
         [CONFIGURATIONS [Debug|Release|...]]
         [COMPONENT <component>]
         [NAMELINK_COMPONENT <component>]
         [OPTIONAL] [EXCLUDE_FROM_ALL]
         [NAMELINK_ONLY|NAMELINK_SKIP]
        ] [...]
        [INCLUDES DESTINATION [<dir> ...]]
        )

 TARGETS targets:targets即爲我們通過ADD_EXECUTABLE或ADD_LIBRARY定義的目標文件,可能是可執行二進制,動態庫,靜態庫;
DESTINATION < dir >:dir即爲定義的安裝路徑。安裝路徑可以是絕對/相對路徑,若如果路徑以/開頭,則是絕對路徑,且絕對路徑的情況下,CMAKE_INSTALL_PREFIX就無效了。 
注:如果希望使用CMAKE_INSTALL_PREFIX定義安裝路徑,就需要使用相對路徑,這時候安裝後的路徑就是${CMAKE_INSTALL_PREFIX}/< dir >
其餘參數待筆者使用到再進行補充吧……

(2) 非目標文件:
.sh腳本文件,即爲典型的非目標文件的可執行程序。 
格式:

Installing Files

install(<FILES|PROGRAMS> files...
        TYPE <type> | DESTINATION <dir>
        [PERMISSIONS permissions...]
        [CONFIGURATIONS [Debug|Release|...]]
        [COMPONENT <component>]
        [RENAME <name>] [OPTIONAL] [EXCLUDE_FROM_ALL])

使用方法基本和上述目標文件指令的INSTALL相同,唯一別的不同是,安裝非目標文件之後的權限爲OWNER_EXECUTE, GOUP_EXECUTE, WORLD_EXECUTE,即755權限目錄的安裝。

(3) 目錄:
格式:

Installing Directories

install(DIRECTORY dirs...
        TYPE <type> | DESTINATION <dir>
        [FILE_PERMISSIONS permissions...]
        [DIRECTORY_PERMISSIONS permissions...]
        [USE_SOURCE_PERMISSIONS] [OPTIONAL] [MESSAGE_NEVER]
        [CONFIGURATIONS [Debug|Release|...]]
        [COMPONENT <component>] [EXCLUDE_FROM_ALL]
        [FILES_MATCHING]
        [[PATTERN <pattern> | REGEX <regex>]
         [EXCLUDE] [PERMISSIONS permissions...]] [...])

 DIRECTORY dirs:dirs是所在源文件目錄的相對路徑。但必須注意:abc與abc/有很大區別: 
若是abc,則該目錄將被安裝爲目標路徑的abc;
若是abc/,則代表將該目錄內容安裝到目標路徑,但不包括該目錄本身。
例:

INSTALL(DIRECTORY icons scripts/ DESTINATION share/myproj
    PATTERN "CVS" EXCLUDE
    PATTERN "scripts/*" PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ)

該指令的執行結果是:

將icons目錄安裝到< prefix >/share/myproj;
將scripts/中的內容安裝到< prefix >/share/myproj;
不包含目錄名爲CVS的目錄;
對於scripts/*文件指定權限爲OWNER_EXECUTE, OWNER_WRITE, OWNER_READ, GROUP_EXECUT, GROUP_READ;

三. 基本控制語法

1. IF

IF…ELSE…語法格式基本類似與C語言,大致如下:

IF (expression)
    COMMAND1(ARGS ...)
    COMMAND2(ARGS ...)
    ...
ELSE (expression)
    COMMAND1(ARGS ...)
    COMMAND2(ARGS ...)
    ...
ENDIF (expression)

其中,一定要有ENDIF與IF對應。

(1) IF基本用法:

IF (expression), expression不爲:空,0,N,NO,OFF,FALSE,NOTFOUND或< var >_NOTFOUND,爲真;
IF (not exp), 與上面相反;
IF (var1 AND var2)
IF (var1 OR var2)
IF (COMMAND cmd) 如果cmd確實是命令並可調用,爲真;
IF (EXISTS dir) 如果目錄存在,爲真;
IF (EXISTS file) 如果文件存在,爲真;
IF (file1 IS_NEWER_THAN file2),當file1比file2新,或file1/file2中有一個不存在時爲真,文件名需使用全路徑;
IF (IS_DIRECTORY dir) 當dir是目錄時,爲真;
IF (DEFINED var) 如果變量被定義,爲真;
IF (var MATCHES regex) 此處var可以用var名,也可以用${var};
IF (string MATCHES regex) 當給定變量或字符串能匹配正則表達式regex時,爲真; 
例:

IF ("hello" MATCHES "ell") 
MESSAGE("true") 
ENDIF ("hello" MATCHES "ell") 

(2) 數字比較表達式

IF (var LESS number)
IF (var GREATER number)
IF (var EQUAL number)

(3) 字母表順序比較

IF (var1 STRLESS var2)
IF (var1 STRGREATER var2)
IF (var1 STREQUAL var2)

例1: 
判斷平臺差異:

IF(WIN32)
    MESSAGE(STATUS "This is windows.")
ELSE(WIN32)
    MESSAGE(STATUS "This is not windows.")
ENDIF(WIN32)

上述代碼可以控制不同平臺進行不同控制。

注:也許ELSE(WIN32)之類的語句閱讀起來很不舒服,這時候可以加上語句:

SET(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON)

這時候上述結構就可以寫成:

IF(WIN32)
ELSE()
ENDIF()

例2: 
配合ELSEIF使用,不同平臺上的控制:

IF(WIN32)
    #do something related to WIN32
ELSEIF(UNIX)
    #do something related to UNIX
ELSEIF(APPLE)
    #do something related to APPLE
ENDIF (WIN32)

2. WHILE

語法結構如下:

WHILE(condition)
    COMMAND1(ARGS ...)
    COMMAND2(ARGS ...)
    ...
ENDWHILE(condition)

真假判斷條件可以參考IF指令。

3. FOREACH

FOREACH有三種使用形式的語法,且每個FOREACH都需要一個ENDFOREACH()與之匹配。

(1) 列表語法

FOREACH(loop_var arg1 arg2 ...)
     COMMAND1(ARGS ...)
     COMMAND2(ARGS ...)
 ...
ENDFOREACH(loop_var)

例:

AUX_SOURCE_DIRECTORY(. SRC_LIST)
FOREACH(F ${SRC_LIST})
     MESSAGE(${F})
ENDFOREACH(F)

該例程中,現將當前路徑下的所有源文件列表賦值給變量SRC_LIST,然後遍歷SRC_LIST中的文件,並持續輸出信息,信息內容是當前路徑下所有源文件的名稱。

(2) 範圍語法

FOREACH(loop_var RANGE total)
    COMMAND1(ARGS ...)
    COMMAND2(ARGS ...)
    ...
ENDFOREACH(loop_var)

例:

FOREACH(VAR RANGE 10)
   MESSAGE(${VAR})
ENDFOREACH(VAR)

該例程從0到total(此處爲10),以1爲步進。此處輸出爲:012345678910

(3) 範圍步進語法

FOREACH(loop_var RANGE start stop [step])
    COMMAND1(ARGS ...)
    COMMAND2(ARGS ...)
    ...
ENDFOREACH(loop_var)

從start開始,到stop結束,以step爲步進。 
例:

FOREACH(A RANGE 5 15 3)
    MESSAGE(${A})
ENDFOREACH(A)

此處輸出爲581114


再次感謝琦小蝦 ,本文由《CMake學習筆記(二)——CMake語法》整理,添加而來。

參考鏈接:https://blog.csdn.net/ajianyingxiaoqinghan/article/details/70230902

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章