开始编写CMake

开始

CMake是用来生成Makefile的一个工具,一般编写在名为CMakeLists.txt的文件中

第一个CMakeLists.txt

此用于记录CMake的学习,和官方文档的内容大同小异,所有内容都是经过亲自实践,并记录实践过程

首先是一个示例程序

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

int main (int argc, char *argv[])
{
if (argc < 2)
{
fprintf (stdout, "Usage: %s number\n", argv[0]);
return 1;
}

double inputValue = atof (argv[1]);
double outputValue = sqrt(inputValue);
fprintf (stdout, "The square root of %g is %g\n", inputValue, outputValue);
return 0;
}

接着创建一个CMakeLists.txt文件,对于简单的项目只需三行:

1
2
3
4
5
6
7
8
# set the cmake version
cmake_minimum_required(VERSION 3.5)

# set the project name
project(Tutorial)

# add the executable
add_executable(Tutorial tutorial.c)

官方文档上的cmake版本是3.10,我不清楚是否是因为我的版本过低所以出现了一些错误,首先执行CMake报错(直接在目录下执行cmake即可):

–The CXX compiler identification is unknown
CMake Error at CMakeLists.txt:4 (project):
No CMAKE_CXX_COMPILER could be found.
Tell CMake where to find the compiler by setting either the environment
variable “CXX” or the CMake cache entry CMAKE_CXX_COMPILER to the full path to the compiler, or to the compiler name if it is in the PATH.
–Configuring incomplete, errors occurred!

根据信息可以看到错误原因,找不到编译器,解决方法有两个,第一可以安装g++,第二在指定项目名时指定语言即可:

1
project(tutorial LANGUAGES C)

CMake运行成功以后,生成了Makefile,但在执行make时又报错了:

Scanning dependencies of target Tutorial
[ 50%] Building C object CMakeFiles/Tutorial.dir/tutorial.c.o
[100%] Linking C executable Tutorial
CMakeFiles/Tutorial.dir/tutorial.c.o: In function ‘main’:
tutorial.c:(.text+0x66): undefined reference to ‘sqrt’
collect2: error: ld returned 1 exit status
CMakeFiles/Tutorial.dir/build.make:94: recipe for target ‘Tutorial’ failed

可以清晰的看到是链接时出错,我们代码使用了<math.h>,所以还需要链接它的库:

1
2
# link libraries
target_link_libraries(Tutorial m)

还可以添加版本号,所以第一个完整的可以运行的CMakeLists.txt如下:

1
2
3
4
5
6
7
8
9
10
11
# set the cmake version
cmake_minimum_required(VERSION 3.5)

# set the project name
project(tutorial VERSION 0.0.1 LANGUAGES C)

# add the executable
add_executable(Tutorial tutorial.c)

# link libraries
target_link_libraries(Tutorial m)

好吧,我发现官方文档是以C++为例,所以没有遇到我遇到的这些问题,我也不想改了,我就以C语言为例完成CMake的学习吧

添加配置头文件

引入配置头文件,使用CMake生成头文件,通过头文件中的宏为项目写入版本号:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# set the cmake version
cmake_minimum_required(VERSION 3.5)

# set the project name
project(tutorial VERSION 0.0.1 LANGUAGES C)

# The set is used to set the value of a parameter
set (MAJOR_VERSION 0)
set (MINOR_VERSION 1)

# set the configure file
configure_file(
"${PROJECT_SOURCE_DIR}/config.h.in"
"${PROJECT_BINARY_DIR}/config.h"
)

# set include dir
include_directories("${PROJECT_BINARY_DIR}")

# add the executable
add_executable(Tutorial tutorial.c)

# link libraries
target_link_libraries(Tutorial m)

在代码目录中新建config.h.in文件,并写入两个宏:

1
2
#define MAJOR_VERSION @MAJOR_VERSION@
#define MINOR_VERSION @MINOR_VERSION@

在CMake中set就相当于是给变量赋值,即MAJOR_VERSION的值为0,MINOR_VERSION的值为1,在config.h.in中使用@MAJOR_VERSION@就是说这是一个变量,在执行CMake时会将相应的值进行替换。例如生成的config.h为:

1
2
#define MAJOR_VERSION 0
#define MINOR_VERSION 1

在源代码中包含config.h的都文件,就可以使用CMake来控制版本号了:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include "config.h"

int main (int argc, char *argv[])
{
if (argc < 2)
{
fprintf (stdout, "Usage: %s number\nversion is %d.%d\n", argv[0], MAJOR_VERSION, MINOR_VERSION);
return 1;
}

double inputValue = atof (argv[1]);
double outputValue = sqrt(inputValue);
fprintf (stdout, "The square root of %g is %g\n", inputValue, outputValue);
return 0;
}

设置C++版本

设置C++版本,这是官方手册上的内容,但是我用的C似乎不用设置,还是在这里介绍一下吧,设置版本很简单,用上面提到的set为CMake本身自带的环境变量设置就可以:

1
2
3
# specify the C++ standard
set(CMAKE_CXX_STANDARD 11)
set(CMAKE_CXX_STANDARD_REQUIRED True)

使用CMake编译项目

上面也简单提到过怎么进行编译,这里详细说一下我进行编译的步骤:

1
2
3
4
5
6
7
## 创建编译目录并进入
mkdir build
cd build
## 运行cmake生成Makefile到编译目录
cmake ..
## 执行Makefile
make

这样我们就可以执行我编译出来的程序了:

1
2
3
4
5
6
./Tutorial 100
The square root of 100 is 10

./Tutorial
Usage: ./Tutorial number
version is 0.1

开始编写CMake
https://carl-5535.github.io/2021/08/08/CMake/开始编写CMake/
作者
Carl Chen
发布于
2021年8月8日
许可协议