天天看點

CMake介紹(1) - 常用指令及文法CMake簡述

參考部落格:阿飛,https://blog.csdn.net/afei__/article/details/81201039

複制學習,隻是為了增加記憶,如侵權,聯系立删

CMake簡述

1. CMake簡介

  CMake是一個跨平台的安裝編譯工具,可以用簡單的語句來描述所有平台的安裝編譯過程。它能夠輸出各種各樣的makefile或者project檔案,能測試編譯器所支援的C++特性,類似UNIX下的automake。

  CMake的所有語句都寫在一個叫CMakeLists.txt(組态檔)的檔案中。當CMakeLists.txt檔案确定後,可以用cmake指令對相關的變量值進行配置。這個指令必須指向CMakeLists.txt所在的目錄。配置完之後,應用cmake指令生成相應的makefile(Unix環境下)或者project檔案(windows環境下)。

  CMake是一個跨平台的軟體,在很多平台可以使用。但是不同的平台不能互相移植。這就有了CMake的用武之地,我們可以先編寫一個CMakeLists.txt檔案,将需要的.h和.cpp檔案包含進來,然後在不同的平台使用CMake調用各自的編譯器生成各自的工程。

2. CMake常用指令

  在 CMakeLists.txt中,指令名字是不區分大小寫的,而參數和變量是大小寫相關的。

   使用"#"表示注釋該行代碼。

   使用${}進行變量的引用

2.1 指定CMake的最小版本

cmake_minimun_required(VERSION  3.4.1)
           

  這行指令是可選的。但在有些情況下,如果 CMakeLists.txt 檔案中使用了一些高版本 cmake 特有的一些指令的時候,就需要加上這樣一行,提醒使用者更新到該版本之後再執行 cmake。

2.2 設定項目名稱

project(demo)
           

  這個指令不是強制的,但最好都加上。它會引入兩個變量 demo_BINARY_DIR 和 demo_SOURCE_DIR,同時,cmake 自動定義了兩個等價的變量 PROJECT_BINARY_DIR 和 PROJECT_SOURCE_DIR。

2.3 設定編譯類型

add_executable(demo demo.cpp)          #生成可執行檔案
add_library(common STATIC util.cpp)    #生成靜态庫
add_library(common SHARED util.cpp)    #生成動态庫或共享庫
           

  add_library預設生成是靜态庫,通過以上指令生成檔案名字,

  • 在Linux下是:

    demo

    libcommon.a

    libcommon.so

  • 在Windows下是:

    demo.exe

    common.lib

    common.dll

2.4 指定編譯包含的源檔案

2.4.1 明确指定包含哪些源檔案

add_library(demo demo.cpp test.cpp util.cpp)
           

2.4.2 搜尋所有的源檔案

  aux_source_directory(dir VAR)發現一個目錄下所有的源代碼檔案,并将清單存儲在一個變量中。

aux_source_directory(. SRC_LIST)    #搜尋目前目錄下的所有源檔案
add_library(demo ${SRC_LIST})
           

2.4.3 自定義搜尋規則

file(GLOB SRC_LIST "*.cpp" "protocol/*.cpp")
add_library(demo ${SRC_LIST})

# 或者
file(GLOB SRC_LIST "*.cpp")
file(GLOB SRC_PROTOCOL_LIST "protocol/*.cpp")
add_library(demo ${SRC_LIST} ${SRC_PROTOCOL_LIST})

# 或者
aux_source_directory(. SRC_LIST)
aux_source_directory(protocol SRC_PROTOCOL_LIST)
add_library(demo ${SRC_LIST} ${SRC_PROTOCOL_LIST})
           

2.5 查找指定的庫檔案

  find_library(VAR name path)查找到指定的預編譯庫,并将它的路徑存儲在變量中。

2.6 設定包含的目錄

include_directories()
           

2.7 設定連結庫搜尋目錄

link_directories(${CMAKE_CURRENT_SOURCE_DIR}/libs)
           

2.8 設定target需要連接配接的庫

  在windows下,系統會根據連結庫目錄,搜尋xxx.lib檔案,Linux下會搜尋xxx.so或者xxx.a檔案,如果都存在會優先連結動态庫。

target_link_libraries(# 目标庫
                      demo
                      
                      # 目标庫需要連結的庫
                      # log-lib是上面find_library指定的變量名
                      ${log-lib}
)
           

2.8.1 指定連結動态庫或靜态庫

target_link_libraries(demo libface.a)
target_link_libraries(demo libface.so)
           

2.8.2 指定全路徑

target_link_libraries(demo ${CMAKE_CURRENT_SOURCE_DIR}/lib/libface.a)
target_link_libraries(demo ${CMAKE_CURRENT_SOURCE_DIR}/lib/libface.so)
           

2.8.3 指定連結多個庫

target_link_libraries(demo
    ${CMAKE_CURRENT_SOURCE_DIR}/libs/libface.a
    boost_system.a
    boost_thread
    pthread
)
           

2.9 設定變量

2.9.1 set直接設定變量的值

set(SRC_LIST main.cpp test.cpp)
add_executable(demo ${SRC_LIST})
           

2.9.2 set追加設定變量的值

set(SRC_LIST main.cpp)
set(SRC_LIST ${SRC_LIST} test.cpp)
add_executable(demo ${SRC_LIST})
           

2.9.3 list追加或者删除變量的值

set(SRC_LIST main.cpp)
list(APPEND SRC_LIST test.cpp)
list(REMOVE_ITEM SRC_LIST main.cpp)
add_executable(demo ${SRC_LIST})
           

2.10 列印資訊

message(${PROJECT_SOURCE_DIR})
message(WARNING "this is warnning message")
           

2.11 包含其它cmake檔案

include(./common.cmake)               # 指定包含檔案的全路徑
include(def)                          # 在搜尋路徑中搜尋def.cmake檔案
set(CMAKE_MODULE_PATH ${CMAKE_CURRENT_SOURCE_DIR}/cmake)     # 設定include的搜尋路徑
           

3. 條件控制

3.1 if…elseif…else…endif

3.1.1 邏輯判斷和比較

if (expression)
if (not exp)
if (var1 AND var2)
if (var1 OR var2)
if (COMMAND cmd)                      #如果 cmd 确實是指令并可調用為真
if (EXISTS dir) if (EXISTS file)      #如果目錄或檔案存在為真
if (file1 IS_NEWER_THAN file2)        #當file1比file2新,檔案名需使用全路徑
if (IS_DIRECTORY dir)                 #當dir是目錄時為真
if (DEFINED var)                      #如果變量被定義為真
if (var MATCHES regex)          #給定的變量或者字元串能夠比對正規表達式regex時為真,此處var可以用var名,也可以用${var}
if (string MATCHES regex)
           

3.1.2 數字比較

if (variable LESS number)          #LESS小于
if (variable GREATER number)       #GREATER大于
if (variable EQUAL number)         #EQUAL等于
           

3.1.3 字母表順序比較

if (variable STRLESS string)
if (variable STRGREATER string)
if (variable STREQUAL string)
           

3.2 while…endwhile

while(condition)
    ...
endwhile()
           

3.3 foreach…endforeach

  start 表示起始數,stop 表示終止數,step 表示步長。

foreach(loop_var RANGE start stop [step])
    ...
endforeach(loop_var)
           

4. 常用變量

4.1 預定義變量

  • PROJECT_SOURCE_DIR:工程的根目錄;
  • PROJECT_BINARY_DIR:運作cmake指令的目錄,通常是${PROJECT_SOURCE_DIR}/build;
  • PROJECT_NAME:傳回通過project指令定義的項目名稱。
  • CMAKE_CURRENT_SOURCE_DIR:目前處理的CMakeLists.txt所在的路徑。
  • CMAKE_CURRENT_BINARY_DIR:target編譯目錄;
  • CMAKE_CURRENT_LIST_DIR:CMakeLists.txt的完整路徑;
  • CMAKE_CURRENT_LIST_LINE:目前所在的行;
  • CMAKE_MODULE_PATH:定義自己的cmake子產品所在的路徑。
  • EXECUTABLE_OUTPUT_PATH:重新定義目标二進制可執行檔案的存放位置。
  • LIBRARY_OUTPUT_PATH:重新定義目标連結庫檔案的存放位置。

4.2 環境變量

  使用環境變量

$ENV{Name}
           

  寫入環境變量

set(ENV{Name} value)
           

4.3 系統資訊

  • CMAKE_MAJOR_VERSION:cmake 主版本号,比如 3.4.1 中的 3;
  • CMAKE_MINOR_VERSION:cmake 次版本号,比如 3.4.1 中的 4;
  • CMAKE_PATCH_VERSION:cmake 更新檔等級,比如 3.4.1 中的 1;
  • CMAKE_SYSTEM:系統名稱,比如 Linux-­2.6.22;
  • CMAKE_SYSTEM_NAME:不包含版本的系統名,比如 Linux;
  • CMAKE_SYSTEM_VERSION:系統版本,比如 2.6.22;
  • CMAKE_SYSTEM_PROCESSOR:處理器名稱,比如 i686;
  • UNIX:在所有的類 UNIX 平台下該值為 TRUE,包括 OS X 和 cygwin;
  • WIN32:在所有的 win32 平台下該值為 TRUE,包括 cygwin。

4.4 主要開關選項

  • BUILD_SHARED_LIBS:這個開關用來控制預設的庫編譯方式,如果不進行設定,使用 add_library 又沒有指定庫類型的情況下,預設編譯生成的庫都是靜态庫。如果 set(BUILD_SHARED_LIBS ON) 後,預設生成的為動态庫。
  • CMAKE_C_FLAGS:設定 C 編譯選項,也可以通過指令 add_definitions() 添加。
  • CMAKE_CXX_FLAGS:設定 C++ 編譯選項,也可以通過指令 add_definitions() 添加。