當(dāng)前位置:首頁 > 嵌入式培訓(xùn) > 嵌入式學(xué)習(xí) > 講師博文 > 大型程序管理神器之CMake
一.背景知識(shí):
CMake是為了響應(yīng)對(duì)NLM資助的Insight Segmentation和注冊(cè)工具包(ITK)需要一個(gè)強(qiáng)大的跨平臺(tái)構(gòu)建環(huán)境(作為可見人類項(xiàng)目的一部分)而創(chuàng)建的。它受一個(gè)早期系統(tǒng)(稱為pcmaker,由Ken Martin和其他開發(fā)人員創(chuàng)建),支持可視化工具包(VTK)開源3D圖形和可視化系統(tǒng)的影響。為了創(chuàng)建CMake,Kitware的Bill Hoffman包括了來自pcmaker的一些關(guān)鍵想法,并添加了自己的更多功能,考慮采用Unix配置工具的一些功能。初的CMake實(shí)施是在2000年中期,加速發(fā)展發(fā)生在2001年初。由于其他開發(fā)人員納入CMake到自己的系統(tǒng),使得CMake得到了許多改進(jìn)。例如,VXL軟件社區(qū)采用CMake作為其構(gòu)建環(huán)境,提供了許多基本功能。 Brad King添加了幾個(gè)功能,以支持CABLE,自動(dòng)包裝環(huán)境和GCC-XML,以及GE公司研發(fā)對(duì)其測(cè)試基礎(chǔ)架構(gòu)(DART)的支持。而且還增加了其他功能,以支持VTK的構(gòu)建環(huán)境轉(zhuǎn)換為CMake,并支持ParaView,增加一個(gè)并行可視化系統(tǒng),以支持洛斯阿拉莫斯實(shí)驗(yàn)室的高級(jí)計(jì)算實(shí)驗(yàn)室。
本文引用地址://www.einuk.cn/emb/Column/7503.html
特點(diǎn):
CMake是一個(gè)管理操作系統(tǒng)和獨(dú)立編譯方式的、可擴(kuò)展的、開源的系統(tǒng)。與許多跨平臺(tái)系統(tǒng)不同的是,CMake被設(shè)計(jì)成一個(gè)結(jié)合本地環(huán)境的系統(tǒng)。簡單的配置文件放置在每個(gè)源目錄(稱為CMakeLists.txt文件)用于生成標(biāo)準(zhǔn)的構(gòu)建文件(如。makefile在Unix和Windows MSVC項(xiàng)目/工作空間)用于通常的方式。CMake可以生成一個(gè)本地編譯源代碼的構(gòu)建環(huán)境,創(chuàng)建庫,生成包裝器和構(gòu)建可執(zhí)行文件的任意組合。CMake支持in-place和out-of-place構(gòu)建,因此可以支持多個(gè)構(gòu)建從單個(gè)源樹。CMake還支持靜態(tài)和動(dòng)態(tài)庫的構(gòu)建。它的另一個(gè)特點(diǎn)是生成一個(gè)緩存文件,叫CMakeCache.txt,該文件將會(huì)和一個(gè)圖形化編輯器一起使用。例如,當(dāng)CMake運(yùn)行時(shí),它位于文件、庫和可執(zhí)行文件,可能會(huì)遇到可選指令。這些信息是集中在緩存中的,這使得用戶可以改變了前一個(gè)的本地構(gòu)建文件。
CMake 的特點(diǎn)主要有:
1,跨平臺(tái),并可生成 native 編譯配置文件,在 Linux/Unix 平臺(tái),生成 makefile,在蘋果平臺(tái),可以生成 xcode,在 Windows 平臺(tái),可以生成 MSVC 的工程文件。
2,能夠管理大型項(xiàng)目。
3,簡化編譯構(gòu)建過程和編譯過程。CMake的工具鏈非常簡單:cmake+make。
4,可擴(kuò)展,可以為 CMake編寫特定功能的模塊,擴(kuò)充 CMake功能
二.安裝 CMake
cmake 目前已經(jīng)成為各大 Linux 發(fā)行版提供的組件,如Ubuntu中,apt-get install cmake即可,如需要圖形界面,輸入命令:apt-get install cmake-qt-gui即可。如果你使用的操作系統(tǒng)(比如 Windows 或者某些 Linux 版本)沒有提供 cmake 或者包含的版本較舊,建議你直接從 cmake 官方網(wǎng)站下載安裝。
//www.cmake.org/HTML/Download.html
在這個(gè)頁面,提供了源代碼的下載以及針對(duì)各種不同操作系統(tǒng)的二進(jìn)制下載,可以選擇適合自己操作系統(tǒng)的版本下載安裝。
三.Cmake第一個(gè)程序
• 1.編寫hello.c
• 2. 編寫CMakeLists.txt
• 3. 執(zhí)行cmake .
“.” 代表的意思是當(dāng)前目錄,cmake會(huì)查找該目錄下的CMakeList.txt 文件
• 4.執(zhí)行過程,生成Makefile
• 5. 執(zhí)行make
四.Cmake語法詳解
• 1.PROJECT
PROJECT(projectname [CXX] [C] [Java])
若是為省略[]中內(nèi)容,就默認(rèn)全部支持
該句話中,隱式的定義了兩個(gè)變量,下面是CMakeCache.txt里面的文件內(nèi)容,里面有各種剛剛系統(tǒng)配置的變量內(nèi)容,下面我們查看兩個(gè)隱藏變量的內(nèi)容:
• 2. ADD_EXECUTABLE
生成可執(zhí)行文件,可以忽略后綴
語法:
1.add_executable(
2. add_executable(
3. add_executable(
具體更詳細(xì)的可查看官網(wǎng)內(nèi)容說明:
網(wǎng)址:
https://cmake.org/cmake/help/v3.7/command/add_executable.html?highlight=add_exe#command:add_executable
• 3. 設(shè)置變量
語法:
SET(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]])
• 4.添加打印信息
語法:
message([STATUS|WARNING|AUTHOR_WARNING|FATAL_ERROR|SEND_ERROR]
"message to display" ...)
當(dāng)執(zhí)行CMake的命令的時(shí)候,stdout里會(huì)顯示STATUS消息,而stderr上顯示其他error消息。
而cmake的gui程序則會(huì)在log里顯示錯(cuò)誤信息。如下圖:
以下是message其他參數(shù)內(nèi)容
STATUS = 非重要消息;
WARNING = CMake 警告, 會(huì)繼續(xù)執(zhí)行;
AUTHOR_WARNING = CMake 警告 (dev), 會(huì)繼續(xù)執(zhí)行;
SEND_ERROR = CMake 錯(cuò)誤, 繼續(xù)執(zhí)行,但是會(huì)跳過生成的步驟;
FATAL_ERROR = CMake 錯(cuò)誤, 終止所有處理過程;
• 5.ADD_SUBDIRECTORY
ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
增加源目錄,二進(jìn)制目錄
• 6.更換輸出路徑
更改EXECUTABLE_OUTPUT_PATH 和 LIBRARY_OUTPUT_PATH兩變量內(nèi)容
把生成可執(zhí)行文件目錄更改為工程目錄的bin文件下,效果如下:
• 7.若是想make install,需要指定make install 目錄
執(zhí)行cmake命令,更改輸出目錄:
cmake –D CMAKE_PREFIX_FILE=/usr/local
查看CMakeCache.txt
前面的只是單獨(dú)的指定目錄,現(xiàn)在,指定需要make install的內(nèi)容。
語法:
install(TARGETS targets... [EXPORT <export-name>]
[[ARCHIVE|LIBRARY|RUNTIME|FRAMEWORK|BUNDLE|
PRIVATE_HEADER|PUBLIC_HEADER|RESOURCE]
[DESTINATION <dir>][PERMISSIONS permissions...]
[CONFIGURATION][Debug|Release|...]][COMPONENT <component>][OPTIONAL][NAMELINK_ONLY|NAMELINK_SKIP]] [...])
Install 分為不同的書寫版本
分別為:
1. TARGETS版本的install命令
2. FILES版本的install命令
3. PROGRAMS版本的install命令
4. DIRECTORY版本的install命令
5. SCRIPT和CODE版本的install命令
6. EXPORT版本的install命令
具體命令可以去官網(wǎng)查看區(qū)別,現(xiàn)在只闡述較為常用的TARGETS版本的install命令的基本內(nèi)容。
TARGETS格式的install命令規(guī)定了安裝工程中的目標(biāo)(targets)的規(guī)則。可執(zhí)行文件都被當(dāng)做RUNTIME目標(biāo)。靜態(tài)鏈接的庫文件總是被當(dāng)做ARCHIVE目標(biāo)。模塊庫總是被當(dāng)做LIBRARY目標(biāo)。對(duì)于動(dòng)態(tài)庫不是DLL格式的平臺(tái)來說,動(dòng)態(tài)庫會(huì)被當(dāng)做LIBRARY目標(biāo)來對(duì)待。
• 8.靜態(tài)庫和動(dòng)態(tài)庫
ADD_LIBRARY(target [SHARED|STATIC|MODULE] [EXCLUDE_FROM_ALL] source1 source2 ... sourceN)
因此,我們可以
ADD_LIBRARY(hello SHARED source.c)
靜態(tài)庫
ADD_LIBRARY(hello STATIC source.c )
但若是想同時(shí)構(gòu)建target名字相同的時(shí)候,如:
libhello.so 和libhello.a,該怎么辦呢?
這時(shí)候就要用到set_target_properties(target1 target2 ... PROPERTIES prop1 value1 prop2 value2 ...)為一個(gè)目標(biāo)設(shè)置屬性。
你能夠使用任何你想要的屬性/值對(duì),并且在隨后的代碼中調(diào)用GET_TARGET_PROPERTY命令取出屬性的值。
SET_TARGET_PROPERTIES(hello_static PROPERTIES OUTPUT_NAME "hello")
OUTPUT_NAME 也是一個(gè)屬性。
• 9.Include
導(dǎo)入cmake模塊。
在cmake安裝目錄中,一般有很多cmake模塊讓我們?cè)诰帉慍makeLists.txt 的時(shí)候?qū)脒M(jìn)去,具體內(nèi)容如下:
如:如果我們想檢查編譯環(huán)境的時(shí)候,就可以加入CheckCXXCompilerFlag模塊。
下面是該模塊的內(nèi)容:
具體的macro命令與C語言中的宏類似,而foreach等內(nèi)容跟shell語法類似,這里就不詳細(xì)闡述了。
• 10.find_package
語法:
• find_package(
例:
find_package(OpenCV 3.1.0 REQUIRE)
該命令會(huì)查找和加載外部模塊的設(shè)置
而變量
語法詳解:
QUIET設(shè)置不顯示找不到包的信息
REQUIRED 如果找不到就會(huì)停止處理并且顯示錯(cuò)誤信息
上述的信息已經(jīng)能簡單的查找到需要的包了,但是,我們需要更加詳細(xì)的命令來使程序可讀性更高
find_package跟install類似,有兩種模式:
• 1.Module 模式
該模式被使用為上述的簡單編寫,cmake會(huì)去CMAKE_MODULE_PATH中需找Find
如果沒有找到怎么辦呢?
就會(huì)調(diào)用下面的Config模式。
• 2.Config 模式
但如果添加了CONFIG 參數(shù),則會(huì)跳過MODULE模式。
• Config模式將會(huì)去定位一個(gè)配置文件,會(huì)尋找
只要找到了package,就會(huì)定義下列變量:
•
•
•
•
因此,我們可以通過判斷這些變量來確定package是否被找到,也可以在包含庫的時(shí)候使用這些變量。
還可以自己編寫上述兩種配置文件,然后利用:
SET(CMAKE_MODULE_PATH dir)指定查找的目錄
Cmake語法簡單介紹就到此為止了,想要知道更加詳細(xì)的命令信息,可以去官網(wǎng)的參考文檔中查找相關(guān)的語法,一般在查看大型應(yīng)用的過程中,都是通過查看官網(wǎng)的開發(fā)文檔來查看相關(guān)信息,然后通過cmake-gui修改相關(guān)變量,或者執(zhí)行完cmake命令后,去修改CmakeCache命令。
官網(wǎng)文檔地址:https://cmake.org/cmake/help/v3.7/
下面是筆者在實(shí)踐過程中的一點(diǎn)小建議:
1. 當(dāng)我們執(zhí)行make前,不可以刪除CMakeLists.txt文件。
2. 當(dāng)我們把一個(gè)已經(jīng)執(zhí)行過的cmake命令的工程移到其他電腦時(shí),注意刪除CmakeCache.txt文件,再重新執(zhí)行cmake命令。
3. 許多配置是可以在CMakeCache.txt里面修改的,如我們想更改編譯工具,改成arm-linux-gcc。
修改CMakeCache.txt內(nèi)容:
或者CMakeLists.txt里更改。
因?yàn)榻徊婢幾g的時(shí)候需要手動(dòng)配置所調(diào)用的庫文件,因此可以修改變量CMAKE_EXE_LINKER_FLAGS
4. 可以配合pkg-config使用,具體配置和使用方法,因不是本文重點(diǎn),讀者可以自行百度查找相關(guān)信息。更多CMake相關(guān)內(nèi)容請(qǐng)點(diǎn)擊:cmake 簡介