參考資料地址:https://github.com/Akagi201/learning-cmake/blob/master/docs/cmake-practice.pdfgit
1、初識cmakegithub
1. Cmake特色vim
2、初試cmake —— helloworldui
1. 準備工做spa
mkdir -p /backup/cmake開放源代碼
cd /backup/cmakecode
mkdir t1blog
cd t1文檔
在t1目錄創建main.c和CMakeLists.txt文件:it
//main.c
1 #include<stdio.h> 2 int main() 3 { 4 printf("Hello World from t1 Main!\n"); 5 return 0; 6 }
//CMakeLists
1 PROJECT(HELLO) 2 SET(SRC_LIST main.c) 3 MESSAGE(STATUS "This is BINARY dir " ${HELLO_BINARY_DIR} 4 MESSAGE(STATUS "This is SOURCE dir " ${HELLO_SOURCE_DIR}) 5 ADD_EXECTUABLE(hello SRC_LIST)
2. 開始構建
cmake . //生成Makefile、CMakeFiles、CMakeCache.txt等文件
make [VERBOSE=1] //實際構建工程,VERBOSE=1可查看make構建的詳細過程
./hello //運行目標文件
3. CMakeLists.txt代碼解釋
(1)PROJECT指令的語法
PROJECT(projectname [CXX] [C] [Java]) //定義工程名稱,並指定支持的語言(默認支持全部語言)
該指令隱式的定義了兩個cmake變量:<projectname>_BINARY_DIR以及<projectname>_SOURCE_DIR,內部編譯的狀況下,兩個變量相同,如上述工程中均爲/backup/cmake/t1,外部編譯則有所不一樣
同時cmake系統也自動預約義了PROJECT_BINARY_DIR和PROJECT_SOURCE_DIR變量,他們的值分別跟HELLO_BINARY_DIR與HELLO_SOURCE_DIR一致;建議直接使用PROJECT_BINARY_DIR和PROJECT_SOURCE_DIR變量,避免工程名稱的影響
(2)SET指令的語法
SET(VAR [VALUE] [CACHE TYPE DOCSTRING [FORCE]]) //用來顯式的定義變量
如:SET(SRC_LIST main.c),若是有多個源文件:SET(SRC_LIST main.c t1.c t2.c)
(3)MESSAGE指令的語法
MESSAGE([SEND_ERROR | STATUS | FATAL_ERROR] "message to display"...) //用於向終端輸出用戶定義的信息
包含了三種類型:
(4)ADD_EXECUTABLE(hello ${SRC_LIST}) //生成名爲hello的可執行文件,源文件列表由變量SRC_LIST定義,本例等同於ADD_EXECUTABLE(hello main.c)
4. 基本語法規則
(1)變量使用${var}方式取值,可是在IF控制語句中是直接使用變量名
(2)指令(參數1 參數2...) //參數使用括弧括起,參數之間使用空格或分號分開
(3)指令是大小寫無關的,參數和變量是大小寫相關的。建議所有使用大寫指令
5. 清理工程:make clean
6. 內部構建與外部構建(in-source build, out-of-source build)
(1)內部編譯不足:生成的中間臨時文件與代碼文件混在一塊兒,且沒法自動刪除
(2)外部編譯過程
//外部編譯優點:對原有的工程沒有任何影響,全部的活動均發生在編譯目錄(build)
//注意:此時的HELLO_SOURCE_DIR仍然指代工程路徑,即/backup/cmake/t1;而HELLO_BINARY_DIR則指代編譯路徑,即/backup/cmake/t1/build
3、更好的Hello World
在採用外部構建的基礎上(構建目錄爲build子目錄),修改上述Hello World使得更像一個工程,實現目標以下:
1. 準備工做
mkdir -p /backup/cmake/t2
cd /back/cmake/t1 + cp main.c CMakeLists.txt ../t2
2. 添加子目錄src
cd /back/cmake/t2
mkdir src
mv main.c src
每一個目錄的CMakeLists.txt以下:
// /backup/cmake/t2/CMakeLists.txt
1 PROJECT(HELLO) 2 ADD_SUBDIRECTORY(src bin) //bin目錄爲編譯輸出(包含編譯中間結果)的目錄
// /backup/cmake/t2/src/CMakeLists.txt
1 ADD_EXECUTABLE(hello main.c)
mkdir build + cd build
cmake .. + make //構建生成的hello目標文件位於build/bin目錄中
語法解釋(ADD_SUBDIRECTORY指令):
ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
用於向當前工程添加存放源文件的子目錄,並能夠指定中間二進制和目標二進制文件存放的位置,EXCLUDE_FROM_ALL用於將指定目錄從編譯過程當中排除,如工程中的example目錄能夠在工程構建完成後進行單獨構建;若是未指定binary_dir則編譯輸出(包含中間結果)目錄爲build/src(與源文件src目錄對應)
3. 指定目標二進制的保存位置
利用SET指令從新指定最終生成的目標二進制位置(指hello或者共享庫,不包含編譯生成的中間文件)
注:指令加到哪一個CMakeLists.txt?添加原則:在哪裏ADD_EXECUTABLE或ADD_LIBRARY,若是須要改變目標存放路徑,就在哪裏加入上述的定義,本例中爲src子目錄下的CMakeLists.txt
4. 如何安裝?
(1)直接make install //將hello安裝到/usr/bin目錄
(2)直接make install DESTDIR=/tmp/test //安裝到/tmp/test/usr/bin目錄(打包時經常使用)
5. 修改Helloworld支持安裝 (用到cmake的INSTALL指令和CMAKE_INSTALL_PREFIX變量)
(1)添加doc目錄及文件
cd /backup/cmake/t2
mkdir doc
vim doc/hello.txt //填寫任意內容並保存
(2)在工程目錄添加runhello.sh腳本、COPYRIGHT和README
cd /backup/cmake/t2
vim runhello.sh //內容爲hello
touch COPYRIGHT
touch README
(3)改寫各目錄下的CMakeLists.txt文件
注:DESTINATION均使用相對路徑,安裝後的路徑爲${CMAKE_INSTALL_PREFIX}/<DESTINATION定義的路徑>,若採用絕對路徑則CMAKE_INSTALL_PREFIX其實就無效的
6. 運行修改內容
cd build
cmake -D CMAKE_INSTALL_PREFIX=/tmp/t2/usr .. //CMAKE_INSTALL_PREFIX的默認定義是/usr/local
make
make install
進入/tmp/t2目錄查看安裝結果:./usr./usr/share./usr/share/doc./usr/share/doc/cmake./usr/share/doc/cmake/t2./usr/share/doc/cmake/t2/hello.txt./usr/share/doc/cmake/t2/README./usr/share/doc/cmake/t2/COPYRIGHT./usr/bin./usr/bin/hello./usr/bin/runhello.sh