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

#include "calc.h"
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