CMake 入門

本章以一個簡單的例子說明如何使用 CMake 建置基本的執行檔,並且在隨後章節中透過修改這個範例達到一些常見的需求:

  • 如何在 Source Tree 之外執行 Build,不汙染存放原始碼的資料夾?
  • 如何建置 Release、Debug 等不同編譯組態的執行檔?
  • 如何加入額外的編譯、連結選項?
  • 如何指定執行檔輸出位置?

檔案樹

  • ex2/

    • src/
      • CMakeLists.txt
      • calc.c
      • calc.h
      • main.c
  • main.c

#include <stdio.h>
#include "calc.h"

int main()
{
    printf("Square of 2 is %d \n",   Square(2));
    printf("Square of 5 is %d \n\n", Square(5));

    printf("Cube of 2 is %d \n",    Cube(2));
    printf("Cube of 5 is %d \n\n",  Cube(5));
    return 0;
}
  • calc.c
int Cube(int x)
{
    return x * x * x;
}

int Square(int x)
{
    return x * x;
}
  • calc.h
#ifndef CALC_H
#define CALC_H

int Cube(int x);

int Square(int x);

#endif
  • CMakeLists.txt
cmake_minimum_required(VERSION 2.6)
project(ex2)
add_executable(ex2 main.c calc.c)

解說 CMakeLists

本例的 CMakeLists.txt 內容只有三行,其中真正有作用的其實只有最後一行,前兩行皆可省略。

cmake_minimum_required(VERSION 2.6)

這一行功能在確定目前使用的 CMake 版本符合需求,當版本不滿足最低需求時會發出錯誤訊息。即使沒加上這一檢查仍然可以繼續完成建置工作,只是 CMake 會發出警告。

project(ex2)

這一行指定專案的名稱,指定專案名稱最主要的目的在於啟用幾個和環境相關的變數,另外也會在 makefile 增加對應的 target。在這個簡單的專案裡並不會去利用這些變數,所以對建置沒有任何影響。

add_executable(ex2 main.c calc.c)

這一行告訴 CMake 加入一個名為 ex2 之執行檔 target,而且此執行檔是由 main.c 和 calc.c 所編譯成。在同一個 CMakeLists 裡面可以加入多個不同的target,也不一定要和 project 同名。 當一個執行檔所需的原始碼很多時,可以透過變數在前面收集原始碼列表,之後再用 add_executable() 加入。

add_executable() 指令的完整格式如下:

add_executable(<name> [WIN32] [MACOSX_BUNDLE]
              [EXCLUDE_FROM_ALL]
              source1 source2 ... sourceN)

WIN32 和 MACOSX_BUNDLE 用於指定平臺專屬的執行檔類型。舉例來說,在 Windows 建立視窗程式時以 WinMain() 做為程式進入點,如果沒有特別指定連結成視窗程式會發生 _mainCRTStartup 連結錯誤,解決的方式為:

add_executable(exe_name WIN32 source1 source2 ... sourceN)

在非 Windows 環境下參數 WIN32 會被自動忽略。 如果加入了 EXCLUDE_FROM_ALL 表示此 target 不會在 make all 時主動建置,必須在 make 時手工指明或者是當其他 target 提出依賴需求時才會被建置。

建置

當所需的檔案備齊之後,將當前目錄移到 ex2/src/ 下,若所在的平臺備有系統預設的編譯器,執行:

$ cmake .

不要忽略後面的句號(.),這代表目前目錄。也可以依照所使用的編譯環境指定適用的 Generator

$ cmake -G "Unix Makefiles"

$ cmake -G "MSYS Makefiles"

> cmake -G "Visual Studio 9 2008"

完成後 CMake 會在目前的目錄下輸出 makefile 或者 IDE 專案檔,另外還會產生這次建置相關資訊的快取檔,接著執行 make 即可建立程式:

$ make
Note

CMake 所產生出來的 makefile 無法獨立運作,建置過程仍然必須依賴 CMake,因此無法直接將 makefile 搬移到沒有 CMake 的環境中使用。事實上,只要更換環境就應該重新執行 CMake,針對目前環境配置產生 makefile。

使用 make clean 即可刪除剛才 make 輸出的中間檔和 target。

$ make clean

然而 CMake 並不會刪除自身產出的快取和中間檔,也不會生成像 make distclean、make dist 之類的規則。讓這些檔案汙染原始碼是非常糟糕的事情,CMake 對此的解決之道是把 build tree 和 source tree 徹底分離,我們在下一節將會介紹 out-of-source build


书籍推荐