CMake 入门/建置执行档
本章以一个简单的例子说明如何使用 CMake 建置基本的执行档,并且在随后章节中透过修改这个范例达到一些常见的需求:
- 如何在 Source Tree 之外执行 Build,不污染存放原始码的资料夹?
- 如何建置 Release、Debug 等不同编译组态的执行档?
- 如何加入额外的编译、连结选项?
- 如何指定执行档输出位置?
范例
[编辑]档案树
[编辑]- ex2/
- src/
- CMakeLists.txt
- calc.c
- calc.h
- main.c
- src/
档案内容
[编辑]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