CMake使用教程和原理
- 2019 年 12 月 28 日
- 筆記
一、什麼是CMake
CMake是一個主要用於CPP的構建工具。CMake語言是平台無關的中間編譯工具。同一個CMake編譯規則在不同系統平台構建出不同的可執行構建文件。在Linux產生MakeFile,在Windows平台產生Visual Studio工程等。CMake旨在解決各平台的不同Make工具的產生的差異(比如GNU Make, QT的qmake,微軟的nmake, BSD的pmake)。
其實除了CMake構建系統之外,CMake已經發展出一系列開發工具:CMake,CTest,CPack和CDash。
– CMake是負責構建軟件的構建工具。
– CTest是一個測試驅動程序工具,用於運行回歸測試。
– CPack是一種打包工具,用於為使用CMake構建的軟件創建特定於平台的安裝程序。
– CDash是一個Web應用程序,用於顯示測試結果並執行連續的集成測試。
– 其他還有Doxygen和BullseyeCoverage
1.1 CMake的前世今生
項目的通常做法是為Unix平台提供配置腳本和Makefile,為Windows提供Visual Studio項目文件。autoconf / libtool構建軟件的方法不能滿足跨平台的要求。
歷史上曾經出現的1999年的VTK構建系統。該系統由Unix的配置腳本和pcmaker
Windows 的可執行文件組成。pcmaker
是一個C程序,可以讀取Unix Makefile文件並為Windows創建NMake文件。
另一種是是gmake
針對Sun工作站上C ++計算機視覺環境。Sun工作站使用該imake
系統創建Makefile。但是,有時需要Windows端口時,gmake
才創建了系統。Unix編譯器和Windows編譯器均可與此gmake
基於此的系統一起使用。
這兩個系統都存在嚴重缺陷:它們迫使Windows開發人員使用命令行。有經驗的Windows開發人員更喜歡使用集成開發環境(IDE)。
1.2 Cmake的使命
- 創建和源代碼庫隔離的構建目錄,分離開發和構建目錄。易於進行源代碼版本控制。
- CMake是具有管理依賴項,依賴之間的關係。如果變更了源文件,必須重新構建所有依賴該源文件的腳本。
- 並且要求高效的依賴關係解析是耗時短的。
- CMake提供一些易於操作的API,向開發人員屏蔽平台細節。
二、CMake怎麼解決問題
CMake有兩個階段,配置和生成階段。

2.1 配置階段
配置階段解析所有的輸入變量,並存儲在CMakeCache.txt這個文件。這個階段解決了用戶構建一個項目需要依賴的各種輸入參數。
在項目的構建過程中都使用shell級別的環境變量。通常,項目具有指向根目錄位置的PROJECT_ROOT環境變量。還有配置可選或外部程序包。要使構建正常進行,每次執行構建時都需要設置所有這些外部變量。所有CMakeFile在配置階段解決了這個問題。
先來窺探下CMakeCache.txt的構成,CmakeCache.txt由兩部分構成:External Cache Entries和Internal Cache Entries。而CMakeCache.txt是由解析器Parser生成。解析器的匹配器找到各種token。CMakeLists也可以解析外部的CMake語法,他是由「include」 或者「add_subdirectory」包含進來,兩者的區別後面會說到。
解析完這些變量,cmake在內存中有了項目(可執行程序、庫、用戶自定義Command)的構建表達方法。在代碼中一個target用cmTarget對象表示,所有的cmTarget構成了cmMakefile對象。


2.2 生成階段
在生成階段,cmake使用了一套語法解析系統,關鍵的類圖如下。cmMakefile對象存錯了CMakeLists.txt的所有輸入變量。解析器使用了lex/yacc語法解析器,執行構建動作。cmCommand定義了命令的執行動作,並且該動作的注釋在代碼也有注釋。
