CMake 簡(jiǎn)介與使用

2017.07.05

本文希望用短平快的方式,解決Cmake軟件的安裝配置使用問題,更進(jìn)一步的參數(shù)配置與工程測(cè)試、報(bào)錯(cuò)問題解決,可以參考他人文檔,眾人拾柴火焰高,整理好的相關(guān)資源鏈接也一并列出。

簡(jiǎn)介

CMake是眾多Make工具中的一種,就是對(duì)代碼進(jìn)行編譯,測(cè)試以及打包操作。

Make工具里面,比較出名的有GNU Make,QT 的qmake,微軟的MS nmake,BSD Make(pmake),Makepp,等等。這些 Make 工具遵循著不同的規(guī)范和標(biāo)準(zhǔn),所執(zhí)行的 Makefile 格式也千差萬別。這樣就帶來了一個(gè)嚴(yán)峻的問題:如果軟件想跨平臺(tái),必須要保證能夠在不同平臺(tái)編譯。而如果使用上面的 Make 工具,就得為每一種標(biāo)準(zhǔn)寫一次 Makefile ,這將是一件讓人抓狂的工作。

而每次對(duì)出現(xiàn)的問題進(jìn)行解決,即是一次對(duì)效率化的貢獻(xiàn)。因此CMake應(yīng)運(yùn)而生。

它可以讓程序員通過一個(gè)與開發(fā)平臺(tái)無關(guān)的CMakeList.txt文件來定制整個(gè)編譯流程,然后再根據(jù)目標(biāo)用戶的平臺(tái)進(jìn)一步生成所需的Makefile和工程文件,如*nix平臺(tái)的Makefile或者win平臺(tái)下面的VS工程。也是一種“Write once, run everywhere”。

一些比較出名的開源項(xiàng)目以及商業(yè)項(xiàng)目,也都是采用CMake作為項(xiàng)目架構(gòu)系統(tǒng),比如KDE以及OpenCV,奈飛(Netflix),第二人生(Second Life),還有LLVM 和Clang,MySQL等等。

安裝

官網(wǎng)是https://cmake.org?


https://cmake.org/download/ 這里可以下載到對(duì)應(yīng)不同平臺(tái)的安裝包,這里分為源碼包以及二進(jìn)制可執(zhí)行文件兩類。然后根據(jù)需要進(jìn)行下載安裝就好了,對(duì)于*nix下面的安裝,可以看另一篇帖子。


使用

CMake可以支持win和*nix,通過在平臺(tái)環(huán)境上進(jìn)行搜索用于build的文件,windows+VS環(huán)境下,可以幫你生成.sln,vcxproj文件,而在*nix則是makefile,同理MAC OS則是xcode的項(xiàng)目文件。

程序員就可以使用CMakeLists.txt配置文件在本地編譯,鏈接文件,生成這些項(xiàng)目。

例如先創(chuàng)建一個(gè)小程序:


然后在相同目錄下創(chuàng)建一個(gè)CMakeLists.txt文件

其中第一行是 最低的版本號(hào)要求,一般默認(rèn)寫2.6,方便兼容

第二行是項(xiàng)目信息,也就是項(xiàng)目名稱

第三行是指定生成目標(biāo),也就是生成可以被開發(fā)環(huán)境使用的工程項(xiàng)目文件

然后運(yùn)行控制臺(tái),切換到當(dāng)前項(xiàng)目路徑里面,用 cmake . 運(yùn)行程序


這里用VS11.0 完成了編譯,也是CMake自動(dòng)搜索配置路徑得到的。


這里你可以看到,就自動(dòng)從cpp源文件生成了一個(gè)完整的VS項(xiàng)目工程。


如果有多個(gè)源文件存在,則修改CMakeLists.txt,在制定目標(biāo)那一行的文件后面進(jìn)行添加操作

如果源文件眾多,還可以使用aux_source_directory命令,它可以查找指定目錄下的所有源文件,將結(jié)果存進(jìn)指定變量名,語法格式如下:

aux_source_directory(<dir><variable>)


這樣,CMake 會(huì)將當(dāng)前目錄所有源文件的文件名賦值給變量DIR_SRCS,再指示變量DIR_SRCS中的源文件需要編譯成一個(gè)名稱為 Demo 的可執(zhí)行文件。


如果是多個(gè)目錄,多個(gè)源文件,例如路徑有一個(gè)show文件夾,里面包括show.c和show.h

那么需要分別在項(xiàng)目根目錄 test 和 show 目錄里各編寫一個(gè) CMakeLists.txt 文件。為了方便,我們可以先將 show 目錄里的文件編譯成靜態(tài)庫(kù)再由 main 函數(shù)調(diào)用。

這種情況下,根目錄test里面的CMakeLists.txt需要改為:


使用命令add_subdirectory指明本項(xiàng)目包含一個(gè)子目錄 test,這樣 test 目錄下的 CMakeLists.txt 文件和源代碼也會(huì)被處理 。第6行,使用命令target_link_libraries指明可執(zhí)行文件 nihao 需要連接一個(gè)名為 test 的鏈接庫(kù) 。

下面是修改子目錄中的CMakeLists.txt如下:


也是類似,使用命令add_library將 src 目錄中的源文件編譯為靜態(tài)鏈接庫(kù)。

如果目錄在其他路徑,則可以在test項(xiàng)目目錄一層CMakeLists里面添加

include_directories ("${PROJECT_SOURCE_DIR}/show")

進(jìn)階

我們可以讓這個(gè)庫(kù)是可選,因?yàn)槿绻褂酶蟮膸?kù)或者依賴于第三方的庫(kù)時(shí),會(huì)有這個(gè)需求。

也是在頂層的CMakeLists添加

option(USE_SHOW"Use test provided display function"ON)

這個(gè)設(shè)置會(huì)顯示在CMake的GUI中,并且其默認(rèn)值為ON。當(dāng)用戶選擇了之后,這個(gè)值會(huì)被保存在CACHE中,這樣就不需要每次CMAKE都進(jìn)行更改了。

下面就繼續(xù)構(gòu)建和鏈接Show庫(kù)。為了達(dá)到這個(gè)目的,我們可以改變頂層的CMakeLists文件:


配置文件configure_file命令用于加入一個(gè)配置頭文件 config.h ,這個(gè)文件由 CMake 從config.h.in生成,通過這樣的機(jī)制,可以預(yù)定義一些參數(shù)和變量來控制代碼的生成。

在添加函數(shù)庫(kù)這里使用了USE_SHOW來決定我們自己的庫(kù)show是否會(huì)被編譯和使用。注意這里變量EXTRA_LIBS的使用方法。這是保持一個(gè)大的項(xiàng)目看起來比較簡(jiǎn)潔的一個(gè)方法。源代碼中相應(yīng)的變化就比較簡(jiǎn)單了:

#ifdef USE_SHOW

#include"show.h"

#endif

最后當(dāng)然是編寫config.h.in文件

因?yàn)樵谇懊娴呐渲梦募锩?,用到了config.h,里面預(yù)定義了USE_SHOW的值,但是我們不需要直接去編寫它,更方便的辦法是寫一個(gè)config.h.in文件,從CMakeLists.txt中導(dǎo)入配置。

config.h.in文件里面寫下面一句:

#cmakedefine USE_SHOW


Linux下的使用

同理,如果做好了Linux的配置,也是一樣的。

在項(xiàng)目目錄下面使用 cmake .,軟件會(huì)去確認(rèn)當(dāng)前默認(rèn)的編譯工具,比如GNU 4.8.1

然后其他流程類似,不過在Linux下面可以使用ccmake 或者 cmake -i 來打開交互式配置界面方便選擇。

方向鍵選擇不同選項(xiàng),enter鍵進(jìn)行修改,c鍵完成配置,g鍵確認(rèn)生成makefile,其他的操作可以參考界面上的提示。


正文就介紹到這里,如果需要進(jìn)一步學(xué)習(xí)了解的,參考資料整理如下:


安裝和測(cè)試及報(bào)錯(cuò)分析

windows下(測(cè)試可用):CMake簡(jiǎn)要教程

Linux下(沒有Kali環(huán)境進(jìn)行測(cè)試):CMake入門實(shí)戰(zhàn)

報(bào)錯(cuò)分析合集:CMake error合集



最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容