基本使用
安裝:下載下傳二進制包後可直接解壓使用
從源碼安裝則執行指令:./bootstrap; make; make install——嘗試執行bootstrap失敗
使用:cmake dir_path,生成工程檔案或makefile檔案
概念
out-of-source build,與in-source build相對,即将編譯輸出檔案與源檔案放到不同目錄中;
基本結構
- 依賴CMakeLists.txt檔案,項目主目标一個,主目錄中可指定包含的子目錄;
- 在項目CMakeLists.txt中使用project指定項目名稱,add_subdirectory添加子目錄;
- 子目錄CMakeLists.txt将從父目錄CMakeLists.txt繼承設定
文法
文法 | 意義 |
---|---|
# | 注釋 |
set | 顯式定義及指派 |
command (args …) | 指令不分大小寫,參數使用空格分隔 |
Add_executable(${var}) | 變量使用${xxx}引用 |
if(var) … else()/elseif() … endif(var) | 條件語句 |
Foreach(f ${VAR}) … Endforeach(f) | 循環語句 |
WHILE() … ENDWHILE() | 循環語句 |
内部變量
變量名 | 意義 |
---|---|
CMAKE_C_COMPILER | 指定C編譯器 |
CMAKE_CXX_COMPILER | 指定C++編譯器 |
CMAKE_C_FLAGS | 編譯C檔案時的選項,如-g;也可以通過add_definitions添加編譯選項 |
EXECUTABLE_OUTPUT_PATH | 可執行檔案的存放路徑 |
LIBRARY_OUTPUT_PATH | 可執行檔案的存放路徑 |
CMAKE_BUILD_TYPE | build 類型(Debug, Release, …),CMAKE_BUILD_TYPE=Debug |
BUILD_SHARED_LIBS | Switch between shared and static libraries |
内置變量的使用:
- 在CMakeLists.txt中指定,使用set
- cmake指令中使用,如cmake -DBUILD_SHARED_LIBS=OFF
指令
變量名 | 意義 |
---|---|
project (HELLO) | 指定項目名稱,生成的VC項目的名稱 |
${HELLO_SOURCE_DIR} | 表示項目根目錄 |
include_directories (${HELLO_SOURCE_DIR}/Hello) | 指定頭檔案的搜尋路徑,相當于指定gcc的-I參數 |
link_directories (${HELLO_BINARY_DIR}/Hello) | 動态連結庫或靜态連結庫的搜尋路徑,相當于gcc的-L參數 |
add_subdirectory (Hello) | 包含子目錄 |
add_executable (helloDemo demo.cxx demo_b.cxx) | 編譯可執行程式,指定編譯的CXX檔案 |
target_link_libraries(demo Hello) | #将可執行檔案與Hello連接配接成最終檔案demo |
add_library(Hello hello.cxx) | #将hello.cxx編譯成靜态庫如libHello.a |
add_custom_target | |
set_target_properties( … ) | 有很多屬性參數 |
message([FATAL_ERROR] “message to display” …) | 列印消息 |
說明
1,CMAKE生成的makefile能夠處理好.h檔案更改時隻編譯需要的cpp檔案;
FAQ
1) 怎樣獲得一個目錄下的所有源檔案
aux_source_directory() 将dir中所有源檔案(不包括頭檔案)儲存到變量variable中,
然後可以add_executable (ss ${variable})這樣使用。
2) 怎樣指定項目編譯目标
project 指令指定
3) 怎樣添加動态庫和靜态庫
target_link_libraries 指令添加即可
4) 怎樣在執行CMAKE時列印消息
使用 message 指令
5) 怎樣指定頭檔案與庫檔案路徑
include_directories與link_directories
可以多次調用以設定多個路徑 link_directories 僅對其後面的 targets 起作用
6) 怎樣區分debug、release版本
建立debug/release兩目錄,分别在其中執行cmake -DCMAKE_BUILD_TYPE=Debug(或Release),
需要編譯不同版本時進入不同目錄執行make即可;
Debug版會使用參數-g;Release版使用-O3 –DNDEBUG
IF(DEBUG_mode) add_definitions(-DDEBUG) ENDIF()
在執行cmake時增加參數即可,例如cmake -D DEBUG_mode=ON
7) 怎樣設定條件編譯
例如: debug版設定編譯選項DEBUG,并且更改不應改變CMakelist.txt
option(DEBUG_mode "ON for debug or OFF for release" ON)
IF(DEBUG_mode)
add_definitions(-DDEBUG)
ENDIF()
使其生效的方法:首先cmake生成makefile,然後make edit_cache編輯編譯選項;Linux下會打開一個文本框,可以更改,該完後再make生成目标檔案——emacs不支援make edit_cache;
局限:這種方法不能直接設定生成的makefile,而是必須使用指令在make前設定參數;對于debug、release版本,相當于需要兩個目錄,分别先cmake一次,然後分别make edit_cache一次;
期望的效果:在執行cmake時直接通過參數指定一個開關項,生成相應的makefile——可以這樣做,例如cmake –DDEBUGVERSION=ON
8) 怎樣添加編譯宏定義
使用add_definitions指令,見指令部分說明
9) 怎樣添加編譯依賴項
用于確定編譯目标項目前依賴項必須先建構好 add_dependencies
10)怎樣指定目标檔案目錄
建立一個新的目錄,在該目錄中執行cmake生成Makefile檔案,這樣編譯結果會儲存在該目錄——類似
SET_TARGET_PROPERTIES(ss7gw PROPERTIES RUNTIME_OUTPUT_DIRECTORY “${BIN_DIR}”)
11)很多檔案夾,難道需要把每個檔案夾編譯成一個庫檔案?
可以不在子目錄中使用CMakeList.txt,直接在上層目錄中指定子目錄
12)怎樣設定依賴的cmake版本
cmake_minimum_required(VERSION 2.6)
13)相對路徑怎麼指定
p r o j e c t n a m e S O U R C E D I R 表 示 根 源 文 件 目 錄 , {projectname_SOURCE_DIR}表示根源檔案目錄, projectnameSOURCEDIR表示根源檔案目錄,{ projectname _BINARY_DIR}表示根二進制檔案目錄?
14) 怎樣設定編譯中間檔案的目錄
15) 怎樣在IF語句中使用字串或數字比較
數字比較LESS、GREATER、EQUAL,字串比STRLESS、STRGREATER、STREQUAL,
set(CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS ON)
set(AAA abc)
IF(AAA STREQUAL abc)
message(STATUS "true") #應該列印true
ENDIF()
16) 更改h檔案時是否隻編譯必須的cpp檔案
是
17)機器上安裝了VC7和VC8,CMAKE會自動搜尋編譯器,但是怎樣指定某個版本?
vs2015 x64編譯器為例,cmake指令如下:
cmake -G “Visual Studio 14 Win64” path\to\source\dir
去掉Win64,就是32bit:
cmake -G “Visual Studio 14” path\to\source\dir
18)怎樣根據OS指定編譯選項
19) 能否自動執行某些編譯前、後指令?
add_custom_command
官方教程說明
20) 怎樣列印make的輸出
make VERBOSE=1
參考文獻:
- [1] (CMake_Tutorial.pdf)
- [2] CMake使用總結,http://blog.csdn.net/keensword007/archive/2008/07/16/2663235.aspx
- [3] http://www.cmake.org/
- [4] 安裝包中文檔
- [5] Andrej Cedilnik,HOWTO: Cross-Platform Software Development Using CMake,October, 2003
- [6] Cjacker,CMake實踐.PDF
- [7] https://cmake.org/cmake/help/v3.5/command/add_custom_command.html