Directory Structure
CMake在構(gòu)建項(xiàng)目時(shí)使用兩個(gè)主要目錄:源目錄和二進(jìn)制目錄。源目錄是項(xiàng)目源代碼所在的位置,也是CMakeLists文件的位置。二進(jìn)制目錄有時(shí)被稱為構(gòu)建目錄,CMake將在其中放置生成的對(duì)象文件、庫(kù)和可執(zhí)行文件。CMake不會(huì)將任何文件寫(xiě)入源目錄,只會(huì)寫(xiě)入二進(jìn)制目錄。
強(qiáng)烈鼓勵(lì)源代碼和二進(jìn)制目錄不同的源代碼外構(gòu)建。支持源代碼和二進(jìn)制目錄相同的源代碼構(gòu)建,但應(yīng)盡可能避免。源代碼外構(gòu)建使維護(hù)干凈的源代碼樹(shù)變得非常容易,并允許快速刪除構(gòu)建生成的所有文件。使構(gòu)建樹(shù)不同于源樹(shù)也可以很容易地支持單個(gè)源樹(shù)的多個(gè)構(gòu)建。當(dāng)您希望有多個(gè)具有不同選項(xiàng)的構(gòu)建,但只有一個(gè)源代碼副本時(shí),這很有用。
Basic CMake Usage
CMake接收一個(gè)或多個(gè)CMakeLists文件作為輸入,并生成項(xiàng)目文件或Makefile,以供各種本地開(kāi)發(fā)工具使用。
典型的CMake過(guò)程如下:
1.為項(xiàng)目定義一個(gè)或多個(gè)CMakeLists文件;
2.CMake配置(configure)并生成(generate)項(xiàng)目;
3.用戶使用他們最喜歡的本地開(kāi)發(fā)工具構(gòu)建(build)項(xiàng)目。
以下部分詳細(xì)描述了該過(guò)程的每個(gè)步驟。
CMakeLists Files
CMakeLists.txt
是純文本文件,包含CMake語(yǔ)言的項(xiàng)目描述。are plain text files that contain the project description in CMake’s Language. cmake-language
表示為一系列注釋、命令和變量。你可能想知道為什么CMake決定擁有自己的語(yǔ)言,而不是使用現(xiàn)有的語(yǔ)言,如Python、Java或Tcl。主要原因是CMake開(kāi)發(fā)人員不想讓CMake需要額外的工具來(lái)運(yùn)行。通過(guò)要求使用這些其他語(yǔ)言之一,所有CMake用戶都需要安裝該語(yǔ)言,并可能安裝該語(yǔ)言的特定版本。出于性能和功能的原因,這是完成一些CMake工作所需的語(yǔ)言擴(kuò)展的基礎(chǔ)。
Hello World for CMake
首先,讓我們考慮最簡(jiǎn)單的CMakeLists文件。要從一個(gè)源文件編譯可執(zhí)行文件,CMakeLists文件將包含三行:
cmake_minimum_required(VERSION 3.20)
project(Hello)
add_executable(Hello Hello.c)
任何頂層CMakeLists文件的第一行應(yīng)該始終是 cmake_minimum_required
。這允許項(xiàng)目需要給定版本的CMake,此外,還允許CMake向后兼容。
任何頂層CMakeLists文件的下一行都應(yīng)該是project
命令。 此命令設(shè)置項(xiàng)目的名稱,并可以指定其他選項(xiàng),如語(yǔ)言或版本。
對(duì)于項(xiàng)目中CMakeLists.txt文件調(diào)用project
命令的每個(gè)目錄,CMake都會(huì)生成一個(gè)頂級(jí)Makefile或IDE項(xiàng)目文件。該項(xiàng)目將包含CMakeLists.txt文件中的所有目標(biāo)以及由add_subdirectory
命令指定的任何子目錄。如果在add_subdirectory
命令中使用了EXCLUDE_FROM_ALL
選項(xiàng),則生成的項(xiàng)目將不會(huì)出現(xiàn)在頂級(jí)Makefile或IDE項(xiàng)目文件中;這對(duì)于生成在主構(gòu)建過(guò)程中沒(méi)有意義的子項(xiàng)目非常有用。考慮到一個(gè)包含多個(gè)示例的項(xiàng)目可以使用此功能,通過(guò)一次CMake運(yùn)行為每個(gè)示例生成構(gòu)建文件,但不將示例作為正常構(gòu)建過(guò)程的一部分進(jìn)行構(gòu)建。
最后,使用add_executable
命令將可執(zhí)行文件添加到使用給定源文件的項(xiàng)目中。
在這個(gè)例子中,源目錄中有兩個(gè)文件:CMakeLists.txt
和Hello.c
。
接下來(lái)的部分將描述如何使用CMake GUI和命令行界面配置和構(gòu)建項(xiàng)目。
Configure and Generate
創(chuàng)建CMakeLists文件后,CMake處理文本文件并在緩存文件中創(chuàng)建條目。用戶可以編輯CMakeLists文件,或使用CMakegui或ccmake指定緩存值,然后重新配置。接下來(lái),CMake使用緩存條目在用戶所需的構(gòu)建系統(tǒng)(例如Makefile或Visual Studio解決方案)中生成項(xiàng)目。
Running the CMake GUI
CMake包括一個(gè)基于Qt的用戶界面,可以在大多數(shù)平臺(tái)上使用,包括UNIX、Mac OS X和Windows。cmakegui包含在cmake源代碼中,但您需要在系統(tǒng)上安裝Qt才能構(gòu)建它。
在Windows上,可執(zhí)行文件名為cmake-gui.exe,它應(yīng)該位于“開(kāi)始”菜單的“程序文件”下。您的桌面上也可能有一個(gè)快捷方式,或者如果您從源代碼構(gòu)建CMake,它將位于構(gòu)建目錄中。對(duì)于UNIX和Mac用戶,可執(zhí)行文件名為cmake-gui,可以在安裝cmake可執(zhí)行文件的位置找到。GUI將顯示類似于圖1所示的內(nèi)容。前兩個(gè)字段是源代碼和二進(jìn)制目錄。它們?cè)试S您指定要編譯的源代碼的位置,以及應(yīng)將生成的二進(jìn)制文件放置在何處。您應(yīng)該先設(shè)置這兩個(gè)值。如果您指定的二進(jìn)制目錄不存在,將為您創(chuàng)建它。如果CMake之前已經(jīng)配置了二進(jìn)制目錄,那么它將自動(dòng)設(shè)置源代碼樹(shù)。
Running the ccmake Curses Interface
在大多數(shù)UNIX平臺(tái)上,如果支持curses庫(kù),CMake會(huì)提供一個(gè)名為ccmake的可執(zhí)行文件。這個(gè)界面是一個(gè)基于終端的文本應(yīng)用程序,與cmakegui非常相似。要運(yùn)行ccmake,請(qǐng)將目錄更改為要放置二進(jìn)制文件的目錄。然后在命令行上使用源目錄的路徑運(yùn)行ccmake。這將啟動(dòng)如圖2所示的文本界面。
簡(jiǎn)要說(shuō)明顯示在窗口底部。如果按'c'鍵,它將配置項(xiàng)目。您應(yīng)該始終在更改緩存中的值后進(jìn)行配置。要更改值,請(qǐng)使用箭頭鍵選擇緩存條目,然后按enter鍵進(jìn)行編輯。布爾值將使用enter鍵切換。設(shè)置完所有值后,您可以按“g”鍵生成Makefiles并退出。您還可以點(diǎn)擊“h”獲取幫助,點(diǎn)擊“q”退出,點(diǎn)擊“t”切換高級(jí)緩存條目的查看。
Running CMake from the Command Line
從命令行,cmake
可執(zhí)行文件可用于生成項(xiàng)目構(gòu)建系統(tǒng)。這最適合選擇很少或沒(méi)有選擇的項(xiàng)目。對(duì)于像VTK這樣的大型項(xiàng)目,建議使用ccmake
或cmake-gui
。要使用cmake
構(gòu)建項(xiàng)目,首先創(chuàng)建并更改要放置二進(jìn)制文件的目錄。運(yùn)行cmake
,指定源樹(shù)的路徑,并使用 -D 標(biāo)志傳遞任何選項(xiàng)。與ccmake
或cmake-gui
不同,使用cmake
可執(zhí)行文件時(shí),配置和生成步驟被合并為一個(gè)步驟。
Specifying the Compiler to CMake
在某些系統(tǒng)上,您可能有多個(gè)編譯器可供選擇,或者您的編譯器可能位于非標(biāo)準(zhǔn)位置。在這些情況下,您需要向CMake指定所需編譯器的位置。有三種方法可以指定:生成器可以指定編譯器;可以設(shè)置環(huán)境變量;或者可以設(shè)置緩存條目。一些生成器與特定的編譯器相關(guān)聯(lián);例如Visual Studio 19生成器總是使用Microsoft Visual Studio 19編譯器。對(duì)于基于Makefile的生成器,CMake將嘗試一系列常用的編譯器,直到找到一個(gè)可用的。
這些列表可以用環(huán)境變量搶占,這些變量可以在運(yùn)行CMake之前設(shè)置。CC環(huán)境變量指定C編譯器,而CXX指定C++編譯器。例如,您可以使用-DCMAKE_CXX_COMPILER=cl直接在命令行上指定編譯器。運(yùn)行cmake
并選擇編譯器后,如果要更改編譯器,請(qǐng)從空的二進(jìn)制目錄重新開(kāi)始。
編譯器和鏈接器的標(biāo)志也可以通過(guò)設(shè)置環(huán)境變量來(lái)更改。設(shè)置LDFLAGS將初始化鏈接標(biāo)志的緩存值,而CXXFLAGS和CFLAGS將分別初始化CMAKE_CXX_flags和CMAKE_C_flags。
Build Configurations
構(gòu)建配置允許以不同的方式構(gòu)建項(xiàng)目,以進(jìn)行調(diào)試、優(yōu)化或任何其他特殊的標(biāo)志集。CMake默認(rèn)支持Debug、Release、MinSizeRel和RelWithDebInfo配置。
- Debug啟用了基本調(diào)試標(biāo)志。
- Release啟用了基本優(yōu)化。
- MinSizeRel具有生成最小目標(biāo)代碼但不一定是最快代碼的標(biāo)志。
- RelWithDebInfo也使用調(diào)試信息構(gòu)建優(yōu)化的構(gòu)建。
CMake根據(jù)所使用的生成器以略有不同的方式處理配置。盡可能遵循本地構(gòu)建系統(tǒng)的慣例。這意味著使用Makefile和使用Visual Studio項(xiàng)目文件時(shí),配置對(duì)構(gòu)建的影響不同。
Visual Studio IDE支持構(gòu)建配置的概念。Visual Studio中的默認(rèn)項(xiàng)目通常具有調(diào)試和發(fā)布配置。從IDE中,您可以選擇構(gòu)建調(diào)試,文件將使用調(diào)試標(biāo)志構(gòu)建。IDE將所有二進(jìn)制文件放入具有活動(dòng)配置名稱的目錄中。這給構(gòu)建需要從自定義命令作為構(gòu)建過(guò)程的一部分運(yùn)行的程序的項(xiàng)目帶來(lái)了額外的復(fù)雜性。有關(guān)如何處理此問(wèn)題的更多信息,請(qǐng)參閱CMAKE_CFG_INTDIR變量和自定義命令部分。變量CMAKE_CONFIGURATION_TYPES用于告訴CMAKE將哪些配置放入工作區(qū)。
使用基于Makefile的生成器,在運(yùn)行CMake時(shí)只能有一個(gè)配置處于活動(dòng)狀態(tài),并且是用CMake_BUILD_TYPE變量指定的。如果變量為空,則不會(huì)向構(gòu)建中添加任何標(biāo)志。如果變量設(shè)置為配置的名稱,則相應(yīng)的變量和規(guī)則(如CMAKE_CXX_FLAGS_<ConfigName>)將添加到編譯行中。Makefiles不為對(duì)象文件使用特殊的配置子目錄。要構(gòu)建調(diào)試樹(shù)和發(fā)布樹(shù),用戶需要使用CMake的源代碼外構(gòu)建功能創(chuàng)建多個(gè)構(gòu)建目錄,并為每個(gè)構(gòu)建將CMake_build_TYPE設(shè)置為所需的選擇。例如:
# With source code in the directory MyProject
# to build MyProject-debug create that directory, cd into it and
ccmake ../MyProject -DCMAKE_BUILD_TYPE=Debug
# the same idea is used for the release tree MyProject-release
ccmake ../MyProject -DCMAKE_BUILD_TYPE=Release
Building Your Project
運(yùn)行CMake后,您的項(xiàng)目就可以構(gòu)建了。如果你的目標(biāo)生成器基于Makefiles,那么你可以通過(guò)將目錄更改為二叉樹(shù)并鍵入make
(或gmake
或nmake
,視情況而定)來(lái)構(gòu)建你的項(xiàng)目。如果您為Visual Studio等IDE生成了文件,則可以啟動(dòng)IDE,將項(xiàng)目文件加載到其中,然后像往常一樣進(jìn)行構(gòu)建。
另一種選擇是從命令行使用cmake
的--build選項(xiàng)。此選項(xiàng)只是一種方便,允許您從命令行構(gòu)建項(xiàng)目,即使這需要啟動(dòng)IDE。
這就是為簡(jiǎn)單項(xiàng)目安裝和運(yùn)行CMake的全部?jī)?nèi)容。在接下來(lái)的章節(jié)中,我們將更詳細(xì)地考慮CMake,并解釋如何在更復(fù)雜的軟件項(xiàng)目中使用它。