https://cmake.org/cmake/help/v3.18/manual/cmake.1.html
概要
Generate a Project Buildsystem
cmake [\<options\>] \<path-to-source\>
cmake [\<options\>] \<path-to-existing-build\>
cmake [\<options\>] -S \<path-to-source\> -B \<path-to-build\>
Build a Project
cmake --build \<dir\> [\<options\>] [-- \<build-tool-options\>]
Install a Project
cmake --install \<dir\> [\<options\>]
Open a Project
cmake --open \<dir\>
Run a Script
cmake [{-D \<var\>=\<value\>}...] -P \<cmake-script-file\>
Run a Command-Line Tool
cmake -E \<command\> [\<options\>]
Run the Find-Package Tool
cmake --find-package [\<options\>]
View Help
cmake --help[-\<topic\>]
介紹
cmake可執行文件是一個命令行跨平台構建系統生成器的接口。上面概要介紹的各種各樣的命令將會在下面詳細介紹。
使用cmake編譯一個軟件工程,需要構建一個編譯系統。選擇使用cmake構建工程,安裝工程或者僅僅運行相應的構建工具(比如make)。cmake可以使用幫助來了解如何使用。
另一個目的,軟件開發者想要的,寫一個cmake語言的腳本來支持自己的編譯。
圖形化的接口可以代替使用cmake,參考ccmake和cmake-gui。cmake測試和打包工具可以參考ctest和cpack。
更多cmake的信息,查看底部手冊的鏈接。
cmake編譯系統的入門
編譯系統描述了如何編譯一個項目的可執行文件和類庫,從他的源碼,使用編譯工具自動完成。比如,一個編譯系統可以是makefile,可以使用make工具的命令行或是一個集成開發環境(IED)的工程文件。為了避免包含多個編譯系統,一個工程可以抽象的定義一個cmake編譯系統。通過這些文件,cmake可以根據底層的構建器構建本地適合的編譯系統。
為了使用cmake構建編譯系統,如下的內容必須有:
源碼樹
最高層次的目錄必須包含工程的源碼。工程通過cmake-language手冊中介紹的文件定義編譯系統。最外層目錄必須包含CMakeLists.txt文件。這個文件介紹了編譯的目標和依賴的環境,這些介紹在cmake-buildsystem(7)手冊中。
編譯樹
最外層目錄包含編譯系統的文件和編譯的輸出結果,比如可執行文件或者類庫。cmake將會寫入一個CMakeCache.txt文件,用來定義這個目錄是編譯樹,並且把編譯系統配置選項的信息持久化。
為了保持持久化的源碼樹,請使用分開的專用的編譯樹來執行超脫於源碼的編譯。同樣支持在同一源碼內的編譯,把編譯樹與源碼樹放到一起,但是這不建議。
構建
選擇一種編譯系統構建。查看cmake-generators(7)手冊了解所有的構建器。運行cmake --help,查看本地支持的構建器。使用-G選項定義一個構建器或是接收cmake在當前平台上默認選擇的構建器。
當使用一個命令行的構建工具,cmake需要環境變量中有需要的編譯工具鏈。如果使用IDE,就不需要對應的環境變量了。
構建一個工程編譯系統
運行下面的命令行表達式來定義源碼樹,編譯樹和生成編譯系統:
cmake [<options>] <path-to-source>
用當前的目錄作為編譯樹,<path-to-source>作為源碼樹。定義的目錄可以是絕對路徑也可以是對於當前目錄的相對路徑。源碼樹必須包含CMakeLists.txt並且不能包含CMakeCache.txt,因為后者標明了一個現有的編譯樹。比如:
$ mkdir build ; cd build
$ cmake ../src
cmake [<options>] <path-to-existing-build>
使用<path-to-existing-build>作為編譯樹,從CMakeCache.txt文件加載源碼樹,必須一開始使用前面的命令運行過cmake。目錄必須是絕對路徑或是相對於當前目錄的相對路徑,比如:
$ cd build
$ cmake .
cmake [<options>] -S <path-to-source> -B <path-to-build>
使用<path-to-build>作為編譯樹,<path-to-source>作為源碼樹。定義的路徑可以使絕對路徑也可以是相對路徑。源碼樹必須包含CMakeLists.txt。編譯樹如果沒有,將會自動創建。比如:
$ cmake -S src -B build
所有的<options>都可以是0或者有如下的設置。
構建完成編譯系統后,可以使用本地合適的編譯工具來編譯工程,比如使用Unix的Makefiles構建器:
$ make
$ make install
或者,可以使用選擇本地合適的編譯工具來構建工程。
選項
-S <path-to-source>
要編譯的cmake工程的根目錄
-B <path-to-build>
cmake用作編譯的根目錄。如果目錄不存在,就創建一個。
-C <initial-cache>
預加載一個腳本用作緩存。
當cmake第一次運行在一個空的編譯樹時,會創建一個CMakeCache.txt文件,寫入項目可定制的選項。這個設置可以用作在加載緩存條目時,定義一個文件,在第一次傳入工程cmake文件列表的時候。這個加載的條目比工程默認值權限高。這個給定的文件,應該使用camke的腳本,包含set()命令使用CACHE設置,而不是cache-format文件。
在腳本中CMAKE_SOURCE_DIR和CMAKE_BINARY_DIR的引用會作為源碼和編譯樹的最頂層。
-D <var>:<type>=<value>, -D <var>=<value>
創建或是更新CMake CACHE的條目
當cmake第一次運行與一個空的編譯樹,會創建CMakeCache.txt文件並且填充工程中可配置的設置。這些設置可能被用作定義一個高於工程默認值的選項。對於渴望越來越多的緩存條目,這些選項可能會重復。
如果:<type>已經被設置,那么必須是set()命令中為它的緩存簽名的其中一項。如果:<type>的部分已經丟失了,那么就會創建一個沒有類型的數據,如果也沒有存在一個類型。如果一個工程合集中的命令設置了PATH或者FILEPATH的內容,那么<value>將會被絕對路徑覆蓋。
這個選項同樣可以通過一條語句設置:-D<var>:<type>=<value> or -D<var>=<value>.
-U <globbing_expr>
從CMake CACHE刪除匹配的數據。
這個選項用作從CMakeCache.txt文件中刪除一條或多條數據,全局表達式可以使用*和?。這個選項可能會重復。
使用這個方法,可以使你的CMakeCache.txt不工作
-G <generator-name>
定義一個編譯系統的構建器。
cmake支持多種本地的當前平台的構建系統。構建器的目的是為了生成編譯系統。可用的構建器的名字在cmake-generators(7)手冊中定義了。
如果沒有聲明,cmake就會檢查CMAKE_GENERATOR環境變量,否則按照默認的選項構建。
-T <toolset-spec>
如果支持,定義構建器的工具集合。
有些cmake構建器支持定義一個工具集合告訴本地編譯系統如何選擇編譯器。查看CMAKE_GENERATOR_TOOLSET獲得更詳細信息。
-A <platform-name>
定義構建器支持的平台名稱。
有些cmake構建器支持指定平台名稱給本地的編譯系統,用來選擇編譯器和sdk。查看CMAKE_GENERATOR_PLATFORM獲取更多信息。
-Wno-dev
禁止開發者的警告信息。
禁止的警告信息就是針對CMakeLists.txt文件作者的警告。默認情況下,也會關閉棄用警告。
-Wdev
打開開發者警告。
打開開發者警告就是針對CMakeLists.txt文件作者的警告。默認情況下也會打開棄用警告。
-Werror=dev
對開發者發出警告作為報錯。
對開發這發出警告就是對CMakeLists.txt文件作者的報錯。默認情況下也會打開棄用警告作為報錯。
-Wno-error=dev
使開發者的警告不是報錯。
表示CMakeLists.txt文件的作者的警告不是報錯。默認情況下也會關閉棄用警告作為報錯。
-Wdeprecated
開啟廢棄函數警告。用作CMakeLists.txt文件。
-Wno-deprecated
禁止廢棄函數警告,用作CMakeLists.txt文件。
-Werror=deprecated
使廢棄宏和函數的警告作為錯誤。用作CMakeLists.txt。
-Wno-error=deprecated
不把廢棄宏和函數的警告作為錯誤。用作CMakeLists.txt文件。
-L[A][H]
列出非高級的緩存變量。
將會列出所有的cmake緩存中的非INTERNAL或ADVANCED的變量。對於打印當前的cmake設置非常有效,可以通過-D更改。更改一些變量將會導致更多的變量創建。如果A已經定義了,那么就會打印高級變量。如果H已經定義了,就會打印幫助信息。
-N
查看模式,僅僅加載緩存,並不運行配置和構建的步驟。
--graphviz=[file]
構建圖形相關依賴,查看CMakeGraphVizOptions獲得更多信息。
構建圖形輸入文件,將會包含所有的類庫和可執行文件
--system-information [file]
輸出關於系統的信息。如果在類庫樹的頂層運行,那么也會打印額外的信息,比如緩存、日志文件等。
--log-level=<ERROR|WARNING|NOTICE|STATUS|VERBOSE|DEBUG|TRACE>
設置日志的等級。
message()命令智慧打印比設定的等級一樣或是更高的日志,默認是STATUS。
為了設置日志等級在cmake運行時有效,需要設置CMAKE_MESSAGE_LOG_LEVEL作為緩存的變量。如果命令行和變量都指定了,那么命令行的優先級高。
為了底層的兼容性,--loglevel這個同義詞也可以接受。
--log-context
允許message()命令行打印每個消息的上下文信息。
這個設置知識打開當前運行的cmake的上下文信息。如果想永久的展示所有子序列的上下文信息,需要設置CMAKE_MESSAGE_CONTEXT_SHOW,當命令行指定后CMAKE_MESSAGE_CONTEXT_SHOW會被忽略。
--debug-trycompile
不刪除try_compile()編譯樹,僅僅使用一個try_compile()在同一時間。
不刪除文件和文件夾在創建try_compile()的時候。在調試try_compiles的時候非常有用。可能會更改結果,把try-compiles修改成前面try-compile的舊垃圾,這樣導致測試失敗或是成功,不確定。這個設置最好是僅僅在調試的時候用,每次使用一個。
--debug-output
是cmake運行在調試模式。打印額外的信息,就相當於cmake運行在SEND_ERROR消息下的堆棧跟蹤。
--debug-find
使cmake在查找命令行的時候運行在調試模式,可以打印更多的查找調用信息的調試模式下的標准錯誤。輸出內容被格式化為方便閱讀的,但是不是解析。查看CMAKE_FIND_DEBUG_MODE參數用來調試更多的本地工程部分。
--trace
使cmake運行在trace模式,打印所有的調用執行和從哪里來。
--trace-expand
使cmake在trace模式,與--trace類似,只不過包含了變量的擴展信息。
--trace-format=<format>
使cmake在trace模式,並且設置輸出格式。
<format>可以是如下值:
human
打印每一行內容用可讀的格式,這是默認值。
json-v1
打印每一行內容用json格式。每一個新文件都用換行符分隔。在json內部沒有換行符。如下:
{
"file": "/full/path/to/the/CMake/file.txt",
"line": 0,
"cmd": "add_executable",
"args": ["foo", "bar"],
"time": 1579512535.9687231,
"frame": 2
}
成員有:
file
cmake運行的源文件地址。
line
函數調用的文件中第幾行
cmd
當前調用的函數名
args
所有的參數
time
系統調用的時間戳
frame
堆棧調用的深度
除此之外,第一個json文檔輸出包含了版本信息
{
"version": {
"major": 1,
"minor": 0
}
}
包含了version字段,有major和minor內容。
--trace-source=<file>
使cmake在跟蹤模式,但只輸出指定文件的行。多個設置可以接受。
--trace-redirect=<file>
使cmake在跟蹤模式,並且重定向輸出為file,而不是stderr
--warn-uninitialized
提醒沒有初始化的變量。當沒有初始化的變量使用時,警告。
--warn-unused-vars
提醒沒有使用的變量。查找定義或是設置的變量,但是沒有使用。
--no-warn-unused-cli
不警告命令行的設置。不查找在命令行中定義了但是沒有使用的設置。
--check-system-vars
查找在系統文件中使用有問題的變量。
正常情況系,不使用或是沒初始化的變量僅僅在CMAKE_SOURCE_DIR和CMAKE_BINARY_DIR中查找,這個設置告訴cmake在其他文件中查找。
--profiling-output=<path>
使用--profiling-format為給定的輸出目錄
--profiling-format=<file>
開啟輸出分析數據,由cmake提供的格式。
可以用於分析cmake腳本的執行。第三方程序需要輸出可讀的格式。
目前只支持:骨骼跟蹤的輸出格式,可以通過google chrome或是使用插件進行分析。
編譯一個工程
cmake提供了命令行的表達式用作編譯一個已經構建的工程二進制樹:
cmake --build \<dir\> [\<options\>] [-- \<build-tool-options\>]
這個抽象了一個本地的編譯工具的命令行接口,可以有如下設置:
--build <dir>
工程需要編譯的二進制目錄。這個是必須的,並且必須是第一個
--parallel [<jobs>], -j [<jobs>]
當前可用的最大內核數,如果<jobs>沒有,就使用默認值。
CMAKE_BUILD_PARALLEL_LEVEL環境變量,如果設置了,定義一個默認的平行等級,當設置沒有賦值時。
有些本地的編譯工具一直都使用平行的。設置<jobs>為1可以限制使用一個工作。
--target <tgt>..., -t <tgt>...
編譯<tgt>替換默認是目標。可以設置多個,用空格隔開。
--config <cfg>
對於多個配置工具,選擇配置文件<cfg>
--clean-first
先清理然后再編譯,如果僅僅清理,使用--target clean
--use-stderr
忽略。行為默認在CMake >= 3.0
--verbose, -v
允許詳細的輸出,如果支持的話,包括編譯命令
如果VERBOSE環境變量或是CMAKE_VERBOSE_MAKEFILE緩存設置了,這個參數就被忽略。
--
傳遞保存的設置給本地的工具
運行cmake --編譯,不附帶任何設置
安裝
cmake提供了命令行表達式用於安裝已經構建的工程的二進制樹
cmake --install \<dir\> [\<options\>]
當不使用構建系統或是本地編譯工具編譯工程的時候,可以使用這個編譯工程,然后安裝。設置是:
--install <dir>
工程二進制文件的安裝目錄,這個必須需要,並且是第一個
--config <cfg>
多個配置的構建器,選擇配置<cfg>
--component <comp>
組件形式的安裝,僅僅安裝對應組件<comp>
--prefix <prefix>
覆蓋安裝前綴CMAKE_INSTALL_PREFIX
--strip
在安裝之前卸載
-v, --verbose
允許詳細信息輸出。
如果VERBOSE設置了,這個參數就被忽略
運行cmake --install進行安裝,不附帶任何設置。
打開工程
cmake --open \<dir\>
用相關的程序打開構建的工程,這個只支持一些構建器。
運行腳本
cmake [{-D \<var\>=\<value\>}...] -P \<cmake-script-file\> [-- \<unparsed-options\>...]
把提供的cmake文件當作一個腳本寫入到cmake語言中。沒有設置和構建步驟執行,沒有緩存修改。如果參數用-D定義,必須用-P進行結束。
任何--后面的設置都不會北cmake解析,但是它會被引用到CMAKE_ARGV<n>中傳遞給腳本,包括--自己。
運行命令行工具
cmake提供了內置的命令行表達式
cmake -E \<command\> [\<options\>]
運行cmake -E或者cmake -E help來鏈接命令,有效的命令是:
capabilities
通過json格式輸出cmake的功能,包含如下格式:
version
json結構體的版本信息,包含如下關鍵字:
string
cmake --version展示的全部的版本信息
major
主版本信息
minor
次版本信息
patch
補丁的層次
suffix
cmake版本的前綴
isDirty
bool類型標明cmake編譯的是否是一個污染的樹
generators
列出可能的構建器。每一個構建器都是一個json結構體,包含如下關鍵字:
name
構建器的名字
toolsetSupport
如果構建器支持toolset,就是true
platformSupport
如果構建器支持平台,就是true
extraGenerators
列出所有擴展的構建器,使用同一個構建器兼容的。
fileApi
可選的成員,當cmake-file-api(7)可用時出現,包含一個成員:
requests
一個json數組,包含零個或是多個支持的file-api請求,每一個是一個json結構體,包含如下成員:
kind
定義一個支持的結構體特征
version
版本信息
serverMode
如果支持server-mode就是true
cat <files>...
連接文件並且打印到標准輸出上。
chdir <dir> <cmd> [<arg>...]
切換當前的目錄,並且運行命令
compare_files [--ignore-eol] <file1> <file2>
檢測文件<file1>與<file2>是否相同,相同返回0,不同返回1。--ignore-eol定義了智能換行對比,忽略LF/CRLF的不同。
copy <file>... <destination>
拷貝文件到<destination> (可以是目錄,也可以是文件)。如果多個文件定義了,<destination>必須是目錄,並且必須存在。通配符不支持。拷貝跟蹤符號鏈接。也就是不拷貝符號鏈接,但是拷貝符號鏈接指向的目錄或是文件。
copy_directory <dir>... <destination>
拷貝<dir>的內容到<destination>文件夾。如果<destination>不存在,就創建一個。copy_directory跟蹤符號鏈接
copy_if_different <file>... <destination>
如果修改了,拷貝文件到<destination> (文件或文件夾)。如果多個文件指定了,<destination>必須是目錄並且必須存在。copy_if_different跟蹤符號鏈接
create_symlink <old> <new>
從<old>創建一個新的<new>的符號鏈接
注意 <new>符號鏈接將要創建的目錄,必須存在
echo [<string>...]
顯示參數為文本
echo_append [<string>...]
顯示參數為文本,在同一行
env [--unset=NAME]... [NAME=VALUE]... COMMAND [ARG]...
使用修改的環境變量運行命令。
environment
顯示當前的環境變量
false
什么都不做,退出返回1
make_directory <dir>...
創建目錄,如果需要,也會創建父目錄,如果存在,則忽略
md5sum <file>...
使用md5sum兼容的格式創建文件的md5 checksum
351abe79cd3800b38cdfb25d45015a15 file1.txt
052f86c15bbde68af55c7f7b340ab639 file2.txt
sha1sum <file>...
使用sha1sum兼容的格式創建sha1 checksum
4bb7932a29e6f73c97bb9272f2bdc393122f86e0 file1.txt
1df4c8f318665f9a5f2ed38f55adadb7ef9f559c file2.txt
sha224sum <file>...
使用sha224sum兼容的格式創建sha224 checksum
b9b9346bc8437bbda630b0b7ddfc5ea9ca157546dbbf4c613192f930 file1.txt
6dfbe55f4d2edc5fe5c9197bca51ceaaf824e48eba0cc453088aee24 file2.txt
sha256sum <file>...
使用sha256sum兼容的格式創建sha256 checksum
76713b23615d31680afeb0e9efe94d47d3d4229191198bb46d7485f9cb191acc file1.txt
15b682ead6c12dedb1baf91231e1e89cfc7974b3787c1e2e01b986bffadae0ea file2.txt
sha384sum <file>...
使用sha384sum兼容的格式創建sha384 checksum
acc049fedc091a22f5f2ce39a43b9057fd93c910e9afd76a6411a28a8f2b8a12c73d7129e292f94fc0329c309df49434 file1.txt
668ddeb108710d271ee21c0f3acbd6a7517e2b78f9181c6a2ff3b8943af92b0195dcb7cce48aa3e17893173c0a39e23d file2.txt
sha512sum <file>...
使用sha512sum兼容的格式創建sha512 checksum
2a78d7a6c5328cfb1467c63beac8ff21794213901eaadafd48e7800289afbc08e5fb3e86aa31116c945ee3d7bf2a6194489ec6101051083d1108defc8e1dba89 file1.txt
7a0b54896fe5e70cca6dd643ad6f672614b189bf26f8153061c4d219474b05dad08c4e729af9f4b009f1a1a280cb625454bf587c690f4617c27e3aebdf3b7a2d file2.txt
remove [-f] <file>...
從3.17開始不建議使用。
刪除文件。如果任何列出的文件不存在了,就返回非零的代碼退出,但是沒有日志。-f設置修改行為為退出附帶零的代碼。remove不跟蹤符號鏈接。也就是僅僅刪除符號鏈接,而不刪除符號鏈接指定的文件。
這個實現有很多bug並且經常返回0。如果不破壞向后兼容性就無法修復它。使用rm替換吧。
remove_directory <dir>...
從3.17版本開始廢棄。
刪除<dir>目錄和目錄下的內容。如果目錄不存在,會被忽略。如果是一個符號鏈接,僅僅刪除鏈接。使用rm替換。
rename <oldname> <newname>
重命名文件或文件夾(在同一個卷內)。如果<newname>已經存在,會直接覆蓋。
rm [-rRf] <file> <dir>...
刪除文件<file>或文件夾<dir>。使用-r或-R刪除文件夾和其里面的內容。如果任何一個files/directories列表中的內容不存在,命令會返回一個非零值,然后退出,並且沒有日志。-f參數強制使返回值為零(比如成功)在這種情況。
server
運行cmake-server(7)模式
sleep <number>...
休眠number的秒鍾。
tar [cxt][vf][zjJ] file.tar [<options>] [--] [<pathname>...]
創建或解壓一個tar或zip包,參數是:
- c
創建一個文檔。<pathname>...參數是強制的。
- x
從文檔中解壓到硬盤。<pathname>...可以在僅僅解壓選中的文件或文件夾的時候使用。如果解壓選中的文件或文件夾,必須提供解壓的名字和目錄。-t可以打印
- t
列出文檔內容。<pathname>...可以用作僅僅列出選中的文件和文件夾
- v
提供詳細的信息學。
- z
使用gzip壓縮文檔
- j
使用bzip2壓縮文檔。
- J
使用xz壓縮文檔。
- --zstd
使用Zstandard壓縮文檔。
- --files-from=<file>
讀出給定文件的每一行。空行忽略。每行內容可能不以-開頭,除非--add-file=<name>增加了以-開頭
- --format=<format>
定義創建文檔的格式。支持的有7zip, gnutar, pax, paxr (restricted pax, default), and zip
- --mtime=<date>
定義記錄到tarball目錄的修改時間。
停止解析參數,並且把所有的保留的參數都當作文件名,即使以-開頭
time <command> [<args>...]
運行命令並且記錄過去的時間
touch <file>...
如果<file>不存在,就創建一個,如果<file>存在,就更改訪問和修改的時間
touch_nocreate <file>...
如果存在就創建一個,否則跳過。
true
什么都不做,退出,返回0
windows下定義的命令行工具
下面的這些在cmake -E后面的參數只在windows下有效:
delete_regv <key>
刪除windows的注冊表的key
env_vs8_wince <sdkname>
顯示設置到環境中,有windows CE sdk在vs2005中提供的批處理
env_vs9_wince <sdkname>
顯示有安裝vs2008提供的windows CESDK設置的環境變量的批處理
write_regv <key> <value>
寫入注冊表值
運行查找打包工具
cmake提供了pkg-config,想makefile基礎工程的幫助
cmake --find-package [<options>]
通過find_package()查找包,並且輸出結果標志到stdout。這個可以替換pkg-config來查找安裝的類庫在makefile基礎的工程中或是autoconf基礎的工程中(通過share/aclocal/cmake.m4)
注意
這個模式由於一些限制,並不是很好的支持。保持只是為了兼容,並不建議在新工程中使用。