天天看點

CMake文法及變量介紹

基本使用

安裝:下載下傳二進制包後可直接解壓使用

從源碼安裝則執行指令:./bootstrap; make; make install——嘗試執行bootstrap失敗

使用:cmake dir_path,生成工程檔案或makefile檔案

概念

out-of-source build,與in-source build相對,即将編譯輸出檔案與源檔案放到不同目錄中;

基本結構

  1. 依賴CMakeLists.txt檔案,項目主目标一個,主目錄中可指定包含的子目錄;
  2. 在項目CMakeLists.txt中使用project指定項目名稱,add_subdirectory添加子目錄;
  3. 子目錄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

内置變量的使用:

  1. 在CMakeLists.txt中指定,使用set
  2. 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}表示根源檔案目錄, projectnameS​OURCED​IR表示根源檔案目錄,{ 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

繼續閱讀