Cmake實踐(Cmake Practice)第一部分

參考資料地址:https://github.com/Akagi201/learning-cmake/blob/master/docs/cmake-practice.pdfgit

1、初識cmakegithub

1. Cmake特色vim

  • 開放源代碼
  • 跨平臺
  • 可以管理大型項目
  • 簡化編譯構建和編譯過程(經常使用流程:cmake + make)
  • 高效率
  • 可擴展
  • 每一個目錄編寫一份CMakeLists.txt

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"...)  //用於向終端輸出用戶定義的信息

包含了三種類型:

  • SEND_ERROR,產生錯誤,生成過程被跳過
  • SATUS,輸出前綴爲—的信息。
  • FATAL_ERROR,當即終止全部cmake過程

(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)外部編譯過程

  • 清除上述t1目錄中的除main.c和CMakeLists.txt以外的全部中間文件,特別是CMakeCache.txt
  • 在t1目錄中新建build目錄  //也能夠建在其餘位置
  • 進入build目錄,運行cmake ..  //..表明父目錄,也能夠輸入工程代碼文件的全路徑;最終在build目錄中生成編譯須要的Makefile和其餘中間文件
  • 運行make  //在當前目錄(build)中生成hello目標文件

//外部編譯優點:對原有的工程沒有任何影響,全部的活動均發生在編譯目錄(build)

//注意:此時的HELLO_SOURCE_DIR仍然指代工程路徑,即/backup/cmake/t1;而HELLO_BINARY_DIR則指代編譯路徑,即/backup/cmake/t1/build

3、更好的Hello World

在採用外部構建的基礎上(構建目錄爲build子目錄),修改上述Hello World使得更像一個工程,實現目標以下:

  • 爲工程添加一個子目錄src,用來放置工程源代碼
  • 添加一個子目錄doc,用來放置這個工程的文檔hello.txt
  • 在工程目錄添加文本文件COPYRIGHT, README
  • 在工程目錄添加一個runhello.sh腳本,用來調用hello二進制
  • 將構建後的目標文件放入構建目錄的bin子目錄
  • 最終安裝這些文件:將hello二進制與runhello.sh安裝至/usr/bin,將doc目錄的內容以及COPYRIGHT/README安裝到/usr/share/doc/cmake/t2

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或者共享庫,不包含編譯生成的中間文件

  • SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)  "build/bin"
  • SET(LIBRARY_OUTPUT_PATH ${PROJECT_BINARY_DIR}/lib)  "build/lib"

注:指令加到哪一個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文件

  • 安裝COPYRIGHT和README,直接修改主工程目錄CMakeLists.txt文件,加入以下指令:INSTALL(FILES COPYRIGHT README DESTINATION share/doc/cmake/t2)
  • 安裝runhello.sh,直接修改主工程目錄CMakeLists.txt文件,加入以下指令:INSTALL(PROGRAMS runhello.sh DESTINATION bin)
  • 安裝doc中的hello.txt,有兩種方式:一是經過在doc目錄創建CMakeLists.txt並將doc目錄經過ADD_SUBDIRECTORY加入工程來完成;另外一種是直接在主工程目錄經過INSTALL(DIRECTORY ...)實現——INSTALL(DIRECTORY doc/ DESTINATION share/doc/cmake/t2);其中「doc/」代表安裝doc目錄中的內容,而非整個目錄

注: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

相關文章
相關標籤/搜索