最近从 Pidgin 3 中发现了 Meson 构建系统。在一番学习后,我发现 Meson 是个非常友好的构建工具。
传统构建工具的弊端
Meson 的诞生少不了传统构建工具的推动,传统构建工具的最大弊端就是烂(非常烂)。传统构建工具工作简单,但会耗费开发者很多精力。简单说就是:开发者应该把更多的时间放在代码上,而不是其它的。
最经典的构建工具我想就是 make 了吧,要编译任何一个 C 项目基本都需要先敲这些:
CC = gcc
OBJS = a.o b.o ...
CFLAGS = ...
LIBS = ...
.DEFAULT_GOAL = exe
%.o: %.c
$(CC) $(CFLAGS) -c -o $@ $^
exe: $(OBJS)
$(CC) $(LIBS) -o $@ $^
clean:
rm -rf $(OBJS) exe
看上去就很糟糕,对吧? Makefile 需要设置一系列变量来保证扩展性,比如 $CC
被用来指定编译器。另外,Makefile 里还有一堆让人眼花缭乱的特殊变量(比如 $DEFAULT_GOAL
),这让 Makefile 的可读性也变的很差。最重要的是,Make 有多个变种,比如 GNU Make、BSD Make。如果你的没有注意你的语法而使用到了一些 Make 扩展,你的 Makefile 可能就没法被其它的 Make 构建。所以,Make 的可移植性也很差。
传统 + DLC(GNU 构建系统与 Cmake)
Cmake 一般都见过,那 GNU 构建系统呢?实际上你也用过,在构建软件时运行的 ./configure
就是 GNU 构建系统的一部分。
GNU 构建系统是用来构建大型软件的构建工具,其大部分基于 GNU m4 (很酷的宏处理器)和 make。而 Cmake 则用于构建跨版本的项目。两个构建系统都解决了传统工具在处理大型项目时的不足,而且改进了一点点的可读性。
Cmake 的可读性很难吐槽,直接上代码:
cmake_minimum_required(VERSION 3.13) # CMake version check
project(simple_example) # Create project "simple_example"
set(CMAKE_CXX_STANDARD 14) # Enable c++14 standard
# Add main.cpp file of project root directory as source file
set(SOURCE_FILES main.cpp)
# Add executable target with source files listed in SOURCE_FILES variable
add_executable(simple_example ${SOURCE_FILES})
而 GNU 构建系统的配置则比这更混乱。另外,因为 GNU 构建系统的配置分布在各个文件里,所以贴不出来(
从零开始的友好的构建系统 —— Meson 构建系统
Meson 构建系统的亮点是快速、对用户友好、跨平台、内嵌子项目和支持多语言。
你好世界!
让我们开始一个 Hello World 项目,看看 Meson 管不管用。
$ cd hello # 进入项目
$ meson init # 初始化项目
$ meson setup build # 初始化构建目录
$ cd build # 进入构建目录
$ ninja # 构建
$ ./hello
可以看到,这样就完成了一个 Hello World 项目。可以看到,源文件夹生成了一个 meson.build
文件。这是 meson 的配置文件,内容应该和下面的相似:
project('hello', 'c', version : '0.1',
default_options : ['warning_level=3'])
exe = executable('hello', 'hello.c',
install : true)
test('basic', exe)
第一行用来定义项目,项目名是 hello、语言是 C、版本是 0.1、默认参数是将警告等级设置为 3。第二行设置一个 exe 变量、内容是一个名为 hello 的可执行文件、源文件是 hello.c、且会被安装到系统中。第三行对 exe 进行基本测试。可以看到,配置对开发者来说一目了然。
引入依赖
要引入依赖十分简单,我会在下面引入 glib-2.0:
project('hello', 'c',
version : '0.1',
default_options : ['warning_level=3'])
glib = dependency('glib-2.0')
exe = executable('hello', 'hello.c',
install : true, dependencies : glib)
test('basic', exe)
哈!前后差别只有两行,Meson 会自动在 pkg-config 中搜索依赖并链接到最终的二进制。
多个源文件
使用多个源文件也很简单,只需要用一个列表来替代 hello.c。代码如下:
exe = executable('hello', ['hello.c', 'b.c'],
install : true, dependencies : glib)
强大的测试功能
Meson 可以自动执行项目的测试,这在 C 项目中不多见。它的使用也十分简单,我在这里创建一个简单测试:
/* plus.c */
#include <assert.h>
int main (void) {
assert (2+2 == 4);
}
# meson.build
plus = executable('plus-test', 'plus.c')
test('2+2 Plus', plus)
大功告成!现在你应该能运行 ninja test
来进行单元测试。
对了,ninja
实际上就是 make 的 meson 版。
这篇简单的 Meson 构建系统的介绍到这里就结束了。文章中展示的 Meson 功能其实只是冰山一角,更多信息可以前往 mesonbuild.com 获取。Happy Hacking!