文檔:http://www.cmake.org/Wiki/CMake
簡單好用的構建工具,主頁:http://www.cmake.org
步驟如下:
##第一步,編寫 CMakeLists.txt 文件
PROJECT(main)
SET(SRC_LIST main.cpp)
SET(CMAKE_CXX_COMPILER "clang++")
SET(CMAKE_CXX_FLAGS "-std=c++11 -stdlib=libc++ -Werror -Weverything -Wno-deprecated-declarations -Wno-disabled-macro-expansion -Wno-float-equal -Wno-c++98-compat -Wno-c++98-compat-pedantic -Wno-global-constructors -Wno-exit-time-destructors -Wno-missing-prototypes -Wno-padded -Wno-old-style-cast")
SET(CMAKE_EXE_LINKER_FLAGS "-lc++ -lc++abi")
SET(CMAKE_BUILD_TYPE Debug)
ADD_EXECUTABLE(main ${SRC_LIST})
其中,PROJECT 指定工程名、 SET 是 cmake 變量賦值命令、 ADD_EXECUTABLE 指定生成可執行程序的名字。 括號內的大寫字符串是 cmake 內部預定義變量,這是 CMakeLists.txt 腳本的重點,下面詳細講述:
另外,對於編譯選項,我的原則是嚴己寬人。 也就是說,在我本機上使用最嚴格的編譯選項以發現儘量多 bug, 發佈給其他人的源碼包使用最寬鬆的編譯選項以減少環境差異導致編譯失敗的可能。 前面羅列出來的就是嚴格版的 CMakeLists.txt, 寬鬆版我會考慮: 編譯器改用 GCC(很多人沒裝 clang),忽略所有編譯警告,讓編譯器進行代碼優化,去掉調試信息,添加安裝路徑等要素,具體如下:
PROJECT(main)
SET(SRC_LIST main.cpp)
SET(CMAKE_CXX_COMPILER "g++")
SET(CMAKE_CXX_FLAGS "-std=c++11 -O3")
SET(CMAKE_BUILD_TYPE Release)
ADD_EXECUTABLE(porgram_name ${SRC_LIST})
INSTALL(PROGRAMS porgram_name DESTINATION /usr/bin/)
在 CMakeLists.txt 所在目錄執行
cmake CMakeLists.txt
執行成功的話,你將在該目錄下看到 Makefile 文件
相同目錄下執行
make
這一步,就是在調用編譯器進行編譯,如果存在代碼問題,修正錯誤後重新執行這一步即可,不用再次執行第一、二步
基本上,你的新工程,可以在基於上面的 CMakeLists.txt 進行修改,執行一次第二步後,每次代碼調整隻需執行第三步即可
##使其更像一個工程
採用外部構建 (out-of-source), 構建目錄是工程目錄下的 build 自錄
添加子目錄 src, build
為 src 子目錄建立 CMakeLists.txt, 內容如下:
SET(CMAKE_CXX_COMPILER "clang")
SET(CMAKE_CXX_FLAGS "-Wall -Werror -Wno-long-long -Wno-variadic-macros -fexceptions -DNDEBUG -std=c99")
SET(CMAKE_BUILD_TYPE Debug)
SET(EXECUTABLE_OUTPUT_PATH ${PROJECT_BINARY_DIR}/bin)
ADD_EXECUTABLE(gdt generate_dt.c)
ADD_EXECUTABLE(dt digital_triangle.c)
PROJECT_BINARY_DIR 變量指的編譯發生的當前目錄
PROJECT(dt)
CMAKE_MINIMUM_REQUIRED(VERSION 3.0)
ADD_SUBDIRECTORY(src bin)
ADD_SUBDIRECTORY(source_dir [binary_dir] [EXCLUDE_FROM_ALL]) 這個指令用於向當前工程添加存放源文件的子目錄,並可以指定中間二進制和目標二進制存放的位置。 EXCLUDE_FROM_ALL 參數的含義是將這個目錄從編譯過程中排除
cmake ..
make
可執行文件就生成在 build/bin 目錄
##一些變量
##靜態與動態庫的構建
###簡單的靜態庫的構建
例如源文件的目錄結構如下:
slist
├── build
└── src
├── slist.c
└── slist.h
首先新建文件 slist/CMakeLists.txt, 內容如下:
PROJECT(slist)
CMAKE_MINIMUM_REQUIRED(VERSION 3.0)
ADD_SUBDIRECTORY(src lib)
然後新建文件 slist/src/CMakeLists.txt, 內容如下:
SET(SRC_LIST slist.c)
SET(INSTALL_PREFIX /Users/mwum/code)
SET(CMAKE_CXX_COMPILER "clang")
SET(CMAKE_CXX_FLAGS "-std=c11")
SET(CMAKE_BUILD_TYPE Release)
ADD_LIBRARY(slist STATIC ${SRC_LIST})
INSTALL(TARGETS slist ARCHIVE DESTINATION ${INSTALL_PREFIX}/lib)
INSTALL(FILES slist.h DESTINATION ${INSTALL_PREFIX}/include)
其中的一些變量解釋如下:
安裝方法如下:
cd build
cmake ..
make
make install
執行完上面的命令之後,生成的靜態庫文件 libslist.a 被安裝到 /Users/mwum/code/lib 目錄, src/slist.h 文件被安裝到 /Users/mwum/code/include 目錄
或者將 slist/src/CMakeLists.txt 文件中關於 INSTALL_PREFIX 這個變量的信息刪除,如下:
SET(SRC_LIST slist.c)
SET(CMAKE_CXX_COMPILER "clang")
SET(CMAKE_CXX_FLAGS "-std=c11")
SET(CMAKE_BUILD_TYPE Release)
ADD_LIBRARY(slist STATIC ${SRC_LIST})
INSTALL(FILES slist.h DESTINATION include)
INSTALL(TARGETS slist ARCHIVE DESTINATION lib)
安裝的時候執行如下命令來手動指定要安裝到的目錄
cd build
cmake .. -DCMAKE_INSTALL_PREFIX=/Users/mwum/code
make
make install
如果要刪除被安裝的文件,可執行命令
cat install_manifest.txt | sudo xargs rm
install_manifest.txt 文件記錄了安裝的所有東西的路徑
slist/CMakeLists.txt, 內容如下:
PROJECT(slist)
CMAKE_MINIMUM_REQUIRED(VERSION 3.0)
ADD_SUBDIRECTORY(src lib)
slist/src/CMakeLists.txt, 內容如下:
SET(SRC_LIST slist.c)
SET(INSTALL_PREFIX /Users/mwum/code)
SET(CMAKE_CXX_COMPILER "clang")
SET(CMAKE_CXX_FLAGS "-std=c11")
SET(CMAKE_BUILD_TYPE Release)
ADD_LIBRARY(slist_static STATIC ${SRC_LIST})
SET_TARGET_PROPERTIES(slist_static PROPERTIES OUTPUT_NAME "slist")
ADD_LIBRARY(slist_shared SHARED ${SRC_LIST})
SET_TARGET_PROPERTIES(slist_shared PROPERTIES OUTPUT_NAME "slist")
SET_TARGET_PROPERTIES(slist_shared PROPERTIES VERSION 1.0 SOVERSION 1)
INSTALL(FILES slist.h DESTINATION ${INSTALL_PREFIX}/include)
INSTALL(TARGETS slist_static ARCHIVE DESTINATION ${INSTALL_PREFIX}/lib)
INSTALL(TARGETS slist_shared LIBRARY DESTINATION ${INSTALL_PREFIX}/lib)
其中的一些變量解釋如下:
SET_TARGET_PROPERTIES(target1 target2 ...
PROPERTIES prop1 value1
prop2 value2 ...)