初衷
CMake能用來編寫跨平臺(cross-platform)的構(gòu)建規(guī)則,通過這些規(guī)則來調(diào)用各個平臺的編譯器、鏈接器,生成各個目標(靜態(tài)庫,靜態(tài)庫,或者可執(zhí)行)。
我第一個接觸的大型C++項目是OpenCV,它是基于CMake構(gòu)建的。后來接觸的另一個大型C++項目是Caffe,既提供Makefile也提供CMakeLists.txt。在使用CMake的過程中對CMake的常用語法越發(fā)熟悉,甚至日常工作中的項目代碼也被我用CMake進行構(gòu)建。但是仍然覺得對CMake不夠了解,CMake的不少用法在官方文檔中的描述也感覺有些晦澀、不清晰。
好在CMake是開源項目,覺得CMake文檔寫的爛那就直接翻源碼。而由于越來越多的C/C++開源項目使用CMake進行構(gòu)建,學習和深入理解CMake對于一個C/C++(尤其是跨平臺)程序員來說還是有相當?shù)暮锰幒捅匾?。(當然你也可以用gradle/bazel/buck/please/scons/xmake/emake等來構(gòu)建)
此外,我也仔細看過CMake官方文檔的部分章節(jié),寫過幾篇蹩腳的CMake筆記文檔,了解到通常越新版本的CMake特性越多。這系列blog分析的CMake源碼是CMake-3.14.3版。(不得不吐槽一下:CMake官網(wǎng)打開速度太慢,國內(nèi)各大開源鏡像站點也都不收錄CMake源碼,CMake官方文檔打開也超慢,而且寫的也不夠系統(tǒng),中文博客講CMake的也往往很初級)。如果你是第一次接觸CMake,我覺得你最好先用用CMake,稍微熟悉一點基本用法和一些概念后再來看本篇不遲。
CMake入口:命令行參數(shù)
CMake是什么?或許我們應該從"cmake.exe是什么?"(windows),或file `which cmake`(Linux或Mac)來分析。當我們安裝好CMake,它提供了一個可執(zhí)行文件cmake或cmake.exe,有時候還提供一個GUI版本,比如ccmake或cmake-gui,不過GUI版本可以認為是外科,里子還是cmake命令。
那么cmake命令是什么?其實就是一個C/C++項目編譯出來的可執(zhí)行文件。它或許提供了一大堆支持的函數(shù)、類,但是對外的接口可以說只有一個,那就是main()函數(shù)。當我敲下cmake ..或者cmake .. -DCMAKE_BUILD_TYPE=Debug,再或者cmake --build .,cmake到底會怎么執(zhí)行,其實就是看它的commandline argument parser是怎么處理的了:它能接受的(合法的)命令行參數(shù)有哪些?每一種分別是什么含義?

從$CMAKE_ROOT/Source/cmakemain.cxx可以看出,它肯定支持的三個參數(shù)是:
--build--open-
-E
繼續(xù)看,發(fā)現(xiàn)do_cmake()函數(shù)中處理了其他參數(shù)的情況,而且數(shù)量非常多:
image.png
而我們看看官方文檔對cmake命令行支持的參數(shù)是怎么寫的,先看cmake3.13版本的文檔,可以說是稀巴爛:

再看cmake3.14版本的命令行參數(shù)文檔:

看起來有所改善,把支持的命令行參數(shù)分成了幾個類別,思路上清晰了不少;不過仍然需要改進,比如說
cmake -N這一條沒有被列出,但是其實后文又有提到。
根據(jù)3.14版的文檔可以看出,執(zhí)行cmake命令,支持7大類參數(shù):
- 指定
CMakeLists.txt所在路徑,用來生成目標平臺的構(gòu)建文件如Makefile、.sln、.xcodeproject等(cmake的主要特色) - 執(zhí)行構(gòu)建,相當于用通用的寫法,對生成的目標平臺構(gòu)建描述文件進行調(diào)用,替代具體的"make"、"nmake"等寫法。(個人經(jīng)常用,還可以指定
--target TargetName和--config BUILD_TYPE) - 用VS、XCode等打開工程(我沒用過,我也覺得沒必要)
- 執(zhí)行cmake腳本
- 執(zhí)行命令行工具
- 執(zhí)行
find-package工具(其實很廢柴,和CMakeLists.txt中的find_package()根本不是一會事兒,試了好幾個包都找不到) - 在命令行里查看幫助(已經(jīng)是9012年了,多少年前就有
git help xxx --web在網(wǎng)頁中看幫助文檔了,cmake什么時候支持一下?)
