參考資料地址:https://github.com/Akagi201/learning-cmake/blob/master/docs/cmake-practice.pdfhtml
1、初識cmakegit
1. Cmake特色 開放源代碼 跨平臺 可以管理大型項目 簡化編譯構建和編譯過程(經常使用流程:cmake + make) 高效率 可擴展 每一個目錄編寫一份CMakeLists.txtgithub
2、初試cmake —— helloworldvim
1. 準備工做ui
mkdir -p /backup/cmake開放源代碼
cd /backup/cmakehtm
mkdir t1blog
cd t1文檔
在t1目錄創建main.c和CMakeLists.txt文件:it
複製代碼 //main.c
#include int main() { printf("Hello World from t1 Main!\n"); return 0; }
//CMakeLists PROJECT(HELLO) SET(SRC_LIST main.c) MESSAGE(STATUS "This is BINARY dir " ${HELLO_BINARY_DIR} MESSAGE(STATUS "This is SOURCE dir " ${HELLO_SOURCE_DIR}) 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變量:_BINARY_DIR以及_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
轉發 https://www.cnblogs.com/hg-love-dfc/p/10242391.html