1. 程式人生 > >ubuntu下使用cmake構建應用程式

ubuntu下使用cmake構建應用程式

1. CMake 簡介

  CMake 是一個跨平臺的自動化建構系統,它使用一個名為 CMakeLists.txt 的檔案來描述構建過程,可以產生標準的構建檔案,如 Unix 的 Makefile 或Windows Visual C++ 的 projects/workspaces 。檔案 CMakeLists.txt 需要手工編寫,也可以通過編寫指令碼進行半自動的生成。在 linux 平臺下使用 CMake 生成 Makefile 並編譯的流程如下:

(1)安裝cmake,sudo apt-get install cmake
(2)編寫 CmakeLists.txt。
(3)執行命令“cmake PATH”生成 Makefile ( PATH是CMakeLists.txt 所在的目錄 )
(4)使用 make 命令進行編譯。

2. 例程1

我們以一個簡單的hello world程式來進行除錯:

(1) 編寫helloworld.c

#include <stdio.h>

int main(void)
{
    printf("hello world!!\r\n");
    return 0;
}

(2) 編寫檔案 CMakeLists.txt 並將其與 helloworld.c 放在同一個目錄下

PROJECT(helloworld)
CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
AUX_SOURCE_DIRECTORY(. DIR_SRCS)
ADD_EXECUTABLE
(helloworld ${DIR_SRCS})

  CMakeLists.txt 的語法比較簡單,由命令、註釋和空格組成,其中命令是不區分大小寫的。符號”#”後面的內容被認為是註釋。
  命令由命令名稱、小括號和引數組成,引數之間使用空格進行間隔。例如對此例程中的CMakeLists.txt 檔案進行分析:

(1) 第一行是一條命令,名稱是 PROJECT,引數是 helloworld ,該命令表示專案的名稱是 helloworld。
(2) 第二行的命令限定了 CMake 的版本。
(3) 第三行使用命令 AUX_SOURCE_DIRECTORY 將當前目錄中的原始檔名稱賦值給變數 DIR_SRCS。該命令會把引數 dir 中所有的原始檔名稱賦值給引數 variable
(4) 第四行使用命令 ADD_EXECUTABLE 指示變數 DIR_SRCS 中的原始檔需要編譯成一個名稱為 main 的可執行檔案

3. 例程2

當文件結構如下圖,分層次時:

    example_2
        |
        +----helloworld.c
        |
        +----src
              |
              +----helloworld_1.h
              |
              +----helloworld_1.c

根目錄下的CMakeLists.txt變化如下:

PROJECT(helloworld)
CMAKE_MINIMUM_REQUIRED(VERSION 2.6) 
ADD_SUBDIRECTORY( src )
AUX_SOURCE_DIRECTORY(. DIR_SRCS)
ADD_EXECUTABLE(helloworld ${DIR_SRCS}  )
TARGET_LINK_LIBRARIES( helloworld Test )

(1) 第三行使用命令 ADD_SUBDIRECTORY 指明本專案包含一個子目錄 src 。
(2) 第六行使用命令 TARGET_LINK_LIBRARIES 指明可執行檔案 helloworld 需要連線一個名為Test的連結庫

src子目錄下的CMakeLists.txt如下:

AUX_SOURCE_DIRECTORY(. DIR_TEST1_SRCS)
ADD_LIBRARY ( Test ${DIR_TEST1_SRCS})

  在該檔案中使用命令ADD_LIBRARY 將src目錄中的原始檔編譯為共享庫。
  在執行cmake的過程中,首先解析目錄example2中的CMakeLists.txt ,當程式執行命令ADD_SUBDIRECTORY( src )時進入目錄src對其中的 CMakeLists.txt 進行解析

4. CMakeLists.txt常用語法解析

(1)SET(CMAKE_BUILE_TYPE DEBUG)
  指定編譯型別,debug 或者為release,debug版會生成相關除錯資訊,可以使用GDB 進行,release不會生成除錯資訊。當無法進行除錯時檢視此處是否設定為debug。
  當這個變數值為Debug的時候,Cmake會使用變數CMAKE_FLAGS_DEBUG 和 CMAKE_C_FLAGS_DEBUG。當這個變數值為Release的時候,工程會使用變數CMAKE_CXX_FLAGS_RELEASE和CMAKE_CFLAGS_RELEASE。
(2)SET(CMAKE_C_FLAGS_DEBUG “-g -Wall”)

CMAKE_C_FLAGS_DEBUG —- C 編譯器
CMAKE_CXX_FLAGS_DEBUG —- C++ 編譯器
-g:編譯器在編譯的時候,產生除錯資訊。
-Wall:生成所有警告資訊。一下是具體的選項,可以單獨使用

5. 內部構建與外部構建

  上面的例子都是“內部構建”,會生成很多臨時檔案,或者拷貝到其它電腦使用時需要刪除相應的cache和中間檔案,比較麻煩。使用外部構建會比較簡單。

舉個簡單的例子來說明外部構建,以編譯上面的例程2為例:

(1)在根目錄中新建build目錄
(2)進入build目錄,執行 cmake ..(注意..代表父目錄,因為父目錄存在我們需要的
CMakeLists.txt,如果你在其他地方建立了build 目錄,需要執行cmake <工程的全
路徑>),檢視一下build目錄,就會發現了生成了編譯需要的Makefile以及其它的中間。
(3)執行make構建工程,就會在當前目錄(build目錄)中獲得目標檔案。
這就是out-of-source 外部編譯,一個最大的好處是,對於原有的工程沒有任何影響,所有動作全部發生在編譯目錄build內。