CMake 全稱(chēng)“cross platform make”费坊,是開(kāi)源、跨平臺(tái)的自動(dòng)化構(gòu)建系統(tǒng)。CMake 由 Kitware 開(kāi)發(fā)與維護(hù)喷鸽,來(lái)自使用者的貢獻(xiàn)使得 CMake 快速成長(zhǎng)。
CMake 并不直接建構(gòu)出最終的軟件灸拍,而是依照平臺(tái)做祝、編譯器產(chǎn)生標(biāo)準(zhǔn)的建構(gòu)檔(如 Unix Makefile 或 Visual Studio 的 projects/workspaces),然后再依一般的生成方式使用鸡岗。和標(biāo)準(zhǔn)的 GNU 開(kāi)發(fā)工具相比混槐,CMake 的角色比 Make 更高階,比較接近 Autotools轩性,而且支持多種不同的平臺(tái)與編譯器声登。
雖然跨平臺(tái)是 CMake 的重要特色,但由于 CMake 的簡(jiǎn)單與彈性揣苏,在單一平臺(tái)上使用也很便利捌刮。
前言
- 每一個(gè)需要進(jìn)行 CMake 操作的目錄下面,都必須存在文件 CMakeLists.txt 舒岸。
- CMake 命令不區(qū)分大小寫(xiě)绅作。習(xí)慣上,CMake 命令全小寫(xiě)蛾派,預(yù)定義變量全大寫(xiě)俄认。
- 變量使用
${}
方式取值,但是在if
控制語(yǔ)句中是直接使用變量名洪乍。 -
command(parameter1 parameter2 …)
眯杏,參數(shù)使用括號(hào)括起,參數(shù)之間使用空格或分號(hào)分開(kāi)壳澳。
常用預(yù)定義變量
CMake 的預(yù)定義變量
-
PROJECT_SOURCE_DIR
:工程根目錄岂贩; -
PROJECT_BINARY_DIR
:運(yùn)行 CMake 命令的目錄。建議定義為${PROJECT_SOURCE_DIR}/build
下巷波; -
CMAKE_INCLUDE_PATH
:環(huán)境變量萎津,非 CMake 變量; -
CMAKE_LIBRARY_PATH
:環(huán)境變量抹镊; -
CMAKE_CURRENT_SOURCE_DIR
:當(dāng)前處理的 CMakeLists.txt 文件所在路徑锉屈; -
CMAKE_CURRENT_BINARY_DIR
:target 編譯目錄;- 使用
add_subdirectory
命令可以更改該變量的值垮耳; -
set(EXECUTABLE_OUTPUT_PATH <dir>)
命令不會(huì)對(duì)該變量有影響颈渊,但改變了最終目標(biāo)文件的存儲(chǔ)路徑遂黍。
- 使用
-
CMAKE_CURRENT_LIST_FILE
:輸出調(diào)用該變量的 CMakeLists.txt 的完整路徑; -
CMAKE_CURRENT_LIST_LINE
:輸出該變量所在的行俊嗽; -
CMAKE_MODULE_PATH
:定義自己的 CMake 模塊所在路徑雾家; -
EXECUTABLE_OUTPUT_PATH
:重新定義目標(biāo)二進(jìn)制可執(zhí)行文件的存放位置; -
LIBRARY_OUTPUT_PATH
:重新定義目標(biāo)鏈接庫(kù)文件的存放位置绍豁; -
PROJECT_NAME
:返回由project
命令定義的項(xiàng)目名稱(chēng)榜贴; -
CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS
:用來(lái)控制if…else…
語(yǔ)句的書(shū)寫(xiě)方式。
系統(tǒng)信息預(yù)定義變量
-
CMAKE_MAJOR_VERSION
:CMake 主版本號(hào)妹田,如 3.12.0 中的 3; -
CMAKE_MINOR_VERSION
:CMake 次版本號(hào)鹃共,如 3.12.0 中的 12鬼佣; -
CMAKE_PATCH_VERSION
:CMake 補(bǔ)丁等級(jí),如 3.12.0 中的 0霜浴; -
CMAKE_SYSTEM
:系統(tǒng)名稱(chēng)晶衷,例如 Windows-10.0.17134; -
CMAKE_SYSTEM_NAME
:不包含版本號(hào)的系統(tǒng)名阴孟,如 Windows晌纫; -
CMAKE_SYSTEM_VERSION
:系統(tǒng)版本號(hào),如 10.0.17134永丝; -
CMAKE_SYSTEM_PROCESSOR
:處理器架構(gòu)锹漱,如 AMD64; -
UNIX
:在所有的類(lèi) UNIX 平臺(tái)為 true慕嚷,包括 macOS 和 Cygwin哥牍; -
WIN32
:在所有的 Win32 平臺(tái)為 true,包括 Cygwin喝检。
開(kāi)關(guān)選項(xiàng)
-
BUILD_SHARED_LIBS
:控制默認(rèn)的庫(kù)編譯方式嗅辣;- 如果未進(jìn)行設(shè)置,使用 add_library 時(shí)又沒(méi)有指定庫(kù)類(lèi)型挠说,默認(rèn)編譯生成的庫(kù)都是靜態(tài)庫(kù)澡谭。
-
CMAKE_C_FLAGS
:設(shè)置 C 編譯選項(xiàng); -
CMAKE_CXX_FLAGS
:設(shè)置 C++ 編譯選項(xiàng)损俭。
常用命令
cmake_minimum_required
該語(yǔ)句一般放置在 CMakeLists.txt 的開(kāi)頭蛙奖,用于說(shuō)明 CMake 最低版本要求。
cmake_minimum_required(VERSION 3.5)
上述示例指 CMake 的版本號(hào)最低為 3.5杆兵。
project
project(<PROJECT-NAME>)
-
<PROJECT-NAME>
指工程名稱(chēng)外永。
該命令一般緊跟 cmake_minimum_required
命令之后,定義了工程的名稱(chēng)拧咳。但項(xiàng)目最終編譯生成的可執(zhí)行文件并不一定是這個(gè)項(xiàng)目名稱(chēng)伯顶,而是由另一條命令確定的,后面會(huì)介紹。
執(zhí)行了該命令之后祭衩,將會(huì)自動(dòng)創(chuàng)建兩個(gè)變量:
-
<PROJECT-NAME>_BINARY_DIR
:二進(jìn)制文件保存路徑灶体; -
<PROJECT-NAME>_SOURCE_DIR
:源代碼路徑。
project(Lab)
執(zhí)行了上一條指令掐暮,即定義了一個(gè)項(xiàng)目名稱(chēng) Lab
蝎抽,相應(yīng)的會(huì)生成兩個(gè)變量:Lab_BINARY_DIR
、Lab_SOURCE_DIR
路克。
CMake 中預(yù)定義了兩個(gè)變量:PROJECT_BINARY_DIR
和 PROJECT_SOURCE_DIR
樟结。
在這個(gè)例子中:
-
PROJECT_BINARY_DIR
等價(jià)于Lab_BINARY_DIR
; -
PROJECT_SOURCE_DIR
等價(jià)于Lab_SOURCE_DIR
精算。
建議直接使用 PROJECT_BINARY_DIR
與 PROJECT_SOURCE_DIR
瓢宦,這樣即使項(xiàng)目名稱(chēng)發(fā)生了變化,也不會(huì)影響 CMakeLists.txt 文件灰羽。
關(guān)于 PROJECT_BINARY_DIR
與 PROJECT_SOURCE_DIR
這兩個(gè)變量是否相同的問(wèn)題驮履,涉及到編譯方法是內(nèi)部編譯還是外部編譯。如果是內(nèi)部編譯廉嚼,則這兩個(gè)變量相同玫镐;如果是外部編譯,則兩個(gè)變量不同怠噪。此處對(duì)內(nèi)部編譯與外部編譯做出介紹:
外部構(gòu)建與內(nèi)部構(gòu)建
假設(shè)此時(shí)已經(jīng)完成了 CMakeLists.txt 的編寫(xiě)恐似,在 CMakeLists.txt 所在目錄下,有兩種執(zhí)行 CMake 的方法:
cmake .\\
make
以及
mkdir build
cd .\\build
cmake ..\\
make
第一種方法是內(nèi)部構(gòu)建傍念,第二種方法是外部構(gòu)建蹂喻。上述兩種方法中,最大不同在于 CMake 與 Make 的工作路徑不同捂寿。
內(nèi)部構(gòu)建方法中口四,CMake 生成的中間文件和可執(zhí)行文件都會(huì)存放在項(xiàng)目目錄中;外部構(gòu)建方法中秦陋,中間文件與可執(zhí)行文件都存放在 build 目錄中蔓彩。
建議使用外部構(gòu)建方法。優(yōu)點(diǎn)顯而易見(jiàn):最大限度地保持了代碼目錄的整潔驳概,生成赤嚼、編譯與安裝是不同于項(xiàng)目目錄的其他目錄中,在外部構(gòu)建方法下顺又,PROJECT_SOURCE_DIR
指向目錄與內(nèi)部構(gòu)建相同更卒,為 CMakeLists.txt 所在根目錄;而 PROJECT_BINARY_DIR
不同稚照,它指向 CMakeLists.txt 所在根目錄下的 build 目錄蹂空。
set
set(<variable> <value>… CACHE <type> <docstring> [FORCE])
示例:
set(CMAKE_INSTALL_PREFIX C:\\Program Files\\${PROJECT_NAME})
該示例顯式地將 CMAKE_INSTALL_PREFIX
的值定義為 C:\\Program Files\\${PROJECT_NAME}
俯萌。如此,在外部構(gòu)建情況下執(zhí)行 make install
命令時(shí)上枕,Make 會(huì)將生成的可執(zhí)行文件拷貝到 C:\\Program Files\\${PROJECT_NAME}\\bin
目錄下咐熙。
當(dāng)然,可執(zhí)行文件的安裝路徑 CMAKE_INSTALL_PREFIX
也可以在執(zhí)行 cmake
命令的時(shí)候指定辨萍,cmake
參數(shù)如下:
cmake -D CMAKE_INSTALL_PREFIX="C:\\Program Files\\…"
如果 cmake
參數(shù)和 CMakeLists.txt 文件中都不指定該值的話棋恼,則該值為默認(rèn)值(Windows 下為 C:\\Program Files\\${PROJECT_NAME}
,UNIX 下為 /usr/local
)锈玉。
add_subdirectory
add_subdirectory(source_dir [binary_dir]
[EXCLUDE_FROM_ALL])
-
source_dir
:源文件路徑爪飘; -
[binary_dir]
:中間二進(jìn)制與目標(biāo)二進(jìn)制文件存放路徑; -
[EXECLUDE_FROM_ALL]
:將這個(gè)目錄從編譯過(guò)程中排除拉背。
這個(gè)命令用于向當(dāng)前工程添加存放源文件的子目錄师崎。
include_directories
include_directories([AFTER|BEFORE] [SYSTEM] dir1 [dir2 …])
-
[AFTER|BEFORE]
:追加標(biāo)志,指定控制追加或預(yù)先添加去团; -
[SYSTEM]
:指定該目錄為系統(tǒng)包含目錄; -
dir1, …, dir n
:添加的一系列頭文件搜索路徑穷蛹。
向工程添加多個(gè)特定的頭文件搜索路徑土陪,路徑之間用空格分隔。類(lèi)似于 GCC 中的編譯參數(shù) -l
肴熏,即指定編譯過(guò)程中編譯器搜索頭文件的路徑鬼雀。當(dāng)項(xiàng)目需要的頭文件不在系統(tǒng)默認(rèn)的搜索路徑時(shí),則指定該路徑蛙吏。
add_executable
add_executable(<name> [WIN32] [MACOSX_BUNDLE]
[EXCLUDE_FROM_ALL]
[source1] [source2 …])
-
name
:可執(zhí)行文件名源哩; -
source1, …, source n
:生成該可執(zhí)行文件的源文件。
該命令給出源文件鸦做,并指出需要編譯出的可執(zhí)行文件名励烦。
示例 1:
add_executable(hello main.cpp)
該示例中,利用源文件 main.cpp
泼诱,編譯出名為 hello
的可執(zhí)行文件坛掠。
示例 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})
該示例中,定義了該工程會(huì)生成一個(gè)名為 CRNode
的可執(zhí)行文件治筒,所依賴(lài)的源文件是變量 SRC_LIST
定義的源文件列表屉栓。
如果前面 project()
命令中定義的項(xiàng)目名稱(chēng)也是 CRNode
,沒(méi)有什么問(wèn)題耸袜,兩者之間沒(méi)有任何關(guān)系友多。
add_library
add_library(<name> [STATIC|SHARED|MODULE]
[EXCLUDE_FROM_ALL]
[source1] [source2 …])
-
name
:庫(kù)文件名稱(chēng); -
[STATIC|SHARED|MODULE]
:生成的庫(kù)的文件類(lèi)型(靜態(tài)庫(kù)/共享庫(kù))堤框; -
[EXCLUDE_FROM_ALL]
:表示該庫(kù)不會(huì)被默認(rèn)構(gòu)建域滥; -
source1, …, sourceN
:生成庫(kù)所依賴(lài)的源文件纵柿。
示例:
add_library(hello SHARED ${LIB_hello_SRC})
link_directories
link_directories(directory1 directory2 …)
該命令用于添加外部庫(kù)的搜索路徑。
target_link_libraries
target_link_libraries(<target> … <item>…)
-
target
:目標(biāo)文件骗绕; -
item
:鏈接外部庫(kù)文件藐窄。
指定鏈接目標(biāo)文件時(shí)需要鏈接的外部庫(kù),效果類(lèi)似于 GCC 編譯參數(shù) -L
酬土,解決外部庫(kù)依賴(lài)的問(wèn)題荆忍。
message
message([<mode>] "message to display" …)
-
mode
:確定消息的類(lèi)型:模式 描述 (none)
重要信息 STATUS
附帶信息 WARNING
CMake 警告,繼續(xù)處理 AUTHOR_WARNING
CMake 警告(dev)撤缴,繼續(xù)處理 SEND_ERROR
CMake 錯(cuò)誤刹枉,繼續(xù)處理,但跳過(guò)生成過(guò)程 FATAL_ERROR
CMake 錯(cuò)誤屈呕,停止處理和生成過(guò)程 DEPRECATION
如果分別啟用 CMAKE_ERROR_DEPRECATED
或CMAKE_WARN_DEPRECATED
微宝,則棄用 CMake 錯(cuò)誤或警告,否則無(wú)消息 "message to display"
:需要顯示的文字消息虎眨。
set_target_properties
set_target_properties(target1 target2 …
PROPERTIES prop1 value1
prop2 value2 …)
設(shè)置目標(biāo)的某些屬性蟋软,改變它們構(gòu)建的方式。
該指令為一個(gè)目標(biāo)設(shè)置屬性嗽桩,語(yǔ)法是列出所有用戶(hù)想要變更的文件岳守,然后提供想要設(shè)置的值。用戶(hù)可以使用任何想用的屬性與對(duì)應(yīng)的值碌冶,并在隨后的代碼中調(diào)用 GET_TARGET_PROPERTY
命令取出屬性的值湿痢。
影響目標(biāo)輸出文件的屬性PROPERTIES
詳述如下:
PREFIX、SUFFIX
-
PREFIX
覆蓋了默認(rèn)的目標(biāo)名前綴(如 lib)扑庞; -
SUFFIX
覆蓋了默認(rèn)的目標(biāo)名后綴(如 .so)譬重。
IMPORT_PREFIX、IMPORT_SUFFIX
與 PREFIX
罐氨、SUFFIX
是等價(jià)的屬性臀规,但針對(duì)的是 DLL 導(dǎo)入庫(kù)(即共享庫(kù)目標(biāo))。
OUTPUT_NAME
構(gòu)建目標(biāo)時(shí)栅隐,OUTPUT_NAME
用來(lái)設(shè)置目標(biāo)的真實(shí)名稱(chēng)以现。
LINK_FLAGS
為一個(gè)目標(biāo)的鏈接階段添加額外標(biāo)志。
LINK_FLAGS_<CONFIG>
將為配置 <CONFIG>
添加鏈接標(biāo)志约啊,如 Debug
邑遏、Release
、RelWithDebInfo
恰矩、MinSizeRel
记盒。
COMPILE_FLAGS
設(shè)置附加的編譯器標(biāo)志,在構(gòu)建目標(biāo)內(nèi)的源文件時(shí)用到外傅。
LINKER_LANGUAGE
改變鏈接可執(zhí)行文件或共享庫(kù)的工具纪吮。默認(rèn)值是設(shè)置與庫(kù)中文件相匹配的語(yǔ)言俩檬。
CXX 與 C 是該屬性的公共值。
VERSION碾盟、SOVERSION
VERSION
指定構(gòu)建的版本號(hào)棚辽,SOVERSION
指定構(gòu)建的 API 版本號(hào)。
構(gòu)建或安裝時(shí)冰肴,如果平臺(tái)支持符號(hào)鏈接屈藐,且鏈接器支持 so 名稱(chēng),那么將會(huì)創(chuàng)建恰當(dāng)?shù)姆?hào)鏈接熙尉。
如果只指定兩者中的一個(gè)联逻,缺失的另一個(gè)假定為具有相同版本號(hào)。
示例 1:
set_target_properties(hello_static PROPERTIES OUTPUT_NAME "hello")
示例 2:
set_target_properties(hello PROPERTEIES VERSION 1.2 SOVERSION 1)
該命令用于控制版本检痰,VERSION
指代動(dòng)態(tài)庫(kù)版本包归,SOVERSION
指代 API 版本。
aux_source_directory
查找某個(gè)路徑下的所有源文件铅歼,并將源文件列表存儲(chǔ)到一個(gè)變量中公壤。
aux_source_directory(<dir> <variable>)
示例:
aux_source_directory(. SRC_LIST)
該指令將當(dāng)前目錄下的文件列表全部存入變量 SRC_LIST
中。
install
install
命令可以按照對(duì)象的不同分為多種類(lèi)型:目標(biāo)文件椎椰、非目標(biāo)文件厦幅、目錄。
目標(biāo)文件
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
即通過(guò)add_executable
或add_library
定義的目標(biāo)文件俭识,可能是可執(zhí)行二進(jìn)制文件慨削、動(dòng)態(tài)庫(kù)洞渔、靜態(tài)庫(kù)套媚; -
DESTINATION <dir>
:dir
即定義的安裝路徑。安裝路徑可以是絕對(duì)/相對(duì)路徑磁椒。在絕對(duì)路徑的情況下堤瘤,CMAKE_INSTALL_PREFIX
就無(wú)效了。- 如果希望使用
CMAKE_INSTALL_PREFIX
定義安裝路徑浆熔,就需要使用相對(duì)路徑本辐,這時(shí)候安裝后的路徑就是${CMAKE_INSTALL_PREFIX}\\<dir>
。
- 如果希望使用
非目標(biāo)文件
.sh 腳本文件医增,即為典型的非目標(biāo)文件的可執(zhí)行程序慎皱。
install(<FILES|PROGRAMS> files… DESTINATION <dir>
[PERMISSIONS permissions…]
[CONFIGURATIONS [Debug|Release|…]]
[COMPONENT <component>]
[RENAME <name>] [OPTIONAL] [EXCLUDE_FROM_ALL])
使用方法和上述目標(biāo)文件指令的 install
基本相同。唯一的區(qū)別是叶骨,安裝非目標(biāo)文件之后的權(quán)限還包括 OWNER_EXECUTE
茫多、GOUP_EXECUTE
、WORLD_EXECUTE
忽刽,即 755 權(quán)限目錄的安裝天揖。
目錄
install(DIRECTORY dirs… 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
是所在源文件目錄的相對(duì)路徑夺欲。但必須注意,abc
與abc/
有很大區(qū)別:-
abc
:該目錄將被安裝為目標(biāo)路徑的abc
今膊; -
abc/
:將該目錄內(nèi)容安裝到目標(biāo)路徑些阅,但不包括該目錄本身。
-
示例:
install(DIRECTORY icons scripts/ DESTINATION share/myproj
PATTERN "CVS" EXCLUDE
PATTERN "scripts/*" PERMISSIONS OWNER_EXECUTE OWNER_WRITE OWNER_READ GROUP_EXECUTE GROUP_READ)
該指令的執(zhí)行結(jié)果是:
- 將 icons 目錄安裝到
<prefix>/share/myproj
斑唬; - 將 scripts/ 中的內(nèi)容安裝到
<prefix>/share/myproj
市埋; - 不包含目錄名為 CVS 的目錄;
- 對(duì)于 scripts/* 文件指定權(quán)限為
OWNER_EXECUTE
赖钞、OWNER_WRITE
腰素、OWNER_READ
、GROUP_EXECUT
雪营、GROUP_READ
弓千。
基本控制語(yǔ)法
if
if…else… 語(yǔ)法格式有些類(lèi)似于 Visual Basic .NET:
if(<expression>)
# then section.
COMMAND1(<ARGS> …)
COMMAND2(<ARGS> …)
#…
elseif(<expression2>)
# elseif section.
COMMAND1(<ARGS> …)
COMMAND2(<ARGS> …)
#…
else(<expression>)
# else section.
COMMAND1(<ARGS> …)
COMMAND2(<ARGS> …)
#…
endif(<expression>)
其中,一定要有 endif()
與 if()
對(duì)應(yīng)献起。
if 基本用法
if(<expression>)
:expression
不為0
洋访、OFF
、NO
谴餐、FALSE
姻政、N
、IGNORE
岂嗓、NOTFOUND
汁展、空字符串,或者不含后綴-NOTFOUND
時(shí)厌殉,為真食绿;if(NOT <expression>
:與上一條相反;if(<expr1> AND <expr2>)
if(<expr1> OR <expr2>
if(COMMAND command-name)
:如果command-name
是命令公罕、宏或函數(shù)并可調(diào)用器紧,為真;if(EXISTS path-to-file-or-directory)
:如果給定路徑的文件或目錄存在楼眷,為真铲汪;if(file1 IS_NEWER_THAN file2)
:當(dāng) file1 比 file2 新,或 file1/file2 中有一個(gè)不存在時(shí)為真罐柳,文件名需使用全路徑掌腰;if(IS_DIRECTORY path-to-directory)
:當(dāng)給定路徑是目錄時(shí),為真张吉。注意使用全路徑齿梁;if(DEFINED <variable>)
:如果變量已被定義,為真芦拿;-
if(<variable|string> MATCHES regex)
:當(dāng)給定變量或字符串能匹配正則表達(dá)式 regex 時(shí)士飒,為真查邢。此處的variable
直接使用變量名,而非${variable}
酵幕。-
示例:
if("hello" MATCHES "ell") message("true") endif("hello" MATCHES "ell")
-
數(shù)字比較表達(dá)式
if(<var> LESS <number>)
if(<var> GREATER <number>)
if(<var> EQUAL <number>)
字母表順序比較
if(<var1> STRLESS <var2>)
if(<var1> STRGREATER <var2>)
if(<var1> STREQUAL <var2>)
示例 1:
判斷平臺(tái)差異扰藕。
if(WIN32)
message(STATUS "This is windows.")
else(WIN32)
message(STATUS "This is not windows.")
endif(WIN32)
上述代碼可以控制不同平臺(tái)進(jìn)行不同控制。
也許 else(WIN32)
之類(lèi)的語(yǔ)句閱讀起來(lái)很不舒服芳撒,這時(shí)候可以加上語(yǔ)句:
set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON)
這時(shí)候上述結(jié)構(gòu)就可以寫(xiě)成:
if(WIN32)
message(STATUS "This is windows.")
else()
message(STATUS "This is not windows.")
endif()
示例 2:
if(WIN32)
#do something related to WIN32
elseif(UNIX)
#do something related to UNIX
elseif(APPLE)
#do something related to APPLE
endif(WIN32)
while
while(<condition>)
COMMAND1(<ARGS> …)
COMMAND2(<ARGS> …)
…
endwhile(<condition>)
類(lèi)似于 endif
邓深,while()
也需要 endwhile()
匹配。
真假判斷條件可以參考 if
指令笔刹。
foreach
foreach
有多種使用形式的語(yǔ)法芥备,且每個(gè) foreach()
都需要一個(gè) endforeach()
與之匹配。
列表語(yǔ)法
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)
該示例中舌菜,先將當(dāng)前路徑下的所有源文件列表賦值給變量 SRC_LIST
萌壳,然后遍歷 SRC_LIST
中的文件,并持續(xù)輸出信息日月,信息內(nèi)容是當(dāng)前路徑下所有源文件的名稱(chēng)袱瓮。
范圍語(yǔ)法
foreach(<loop_var> RANGE <total>)
COMMAND1(<ARGS> …)
COMMAND2(<ARGS> …)
…
endforeach(<loop_var>)
示例:
foreach(v RANGE 10)
message(${v})
endforeach(v)
該示例從 0 到 total
(此處為 10),以 1 為步進(jìn)爱咬。此處輸出為:012345678910
尺借。
范圍步進(jìn)語(yǔ)法
foreach(<loop_var> RANGE <start> <stop> [<step>])
COMMAND1(<ARGS> …)
COMMAND2(<ARGS> …)
…
endforeach(<loop_var>)
從 start
開(kāi)始,到 stop
結(jié)束精拟,以 step
為步進(jìn)燎斩。
示例:
foreach(a RANGE 5 15 3)
message(${a})
endforeach(a)
此處輸出為 581114
。
迭代語(yǔ)法
foreach
還可以循環(huán)訪問(wèn)生成的數(shù)字范圍蜂绎。這種迭代有三種類(lèi)型:
- 指定單個(gè)數(shù)字時(shí)栅表,范圍將包含元素
[0, …, total]
(包括total
); - 指定兩個(gè)數(shù)字時(shí)荡碾,范圍將包含從第一個(gè)數(shù)字到第二個(gè)數(shù)字(包括)的元素谨读;
- 第三個(gè)可選數(shù)字是用于從第一個(gè)數(shù)字迭代到第二個(gè)數(shù)字(包括)的增量局装。
foreach(<loop_var> IN [LISTS [<list1> …]]
[ITEMS [<item1> …]])
COMMAND1(<ARGS> …)
COMMAND2(<ARGS> …)
…
endforeach(<loop_var>)
foreach
循環(huán)訪問(wèn)一個(gè)精確的項(xiàng)列表:
-
LISTS
:給要遍歷的列表值變量命名坛吁,包括空元素(空字符串是零長(zhǎng)度列表)。注意宏參數(shù)不是變量铐尚。 -
ITEMS
:結(jié)束參數(shù)解析并包含迭代中它后面的所有參數(shù)拨脉。