Meson构建系统的使用

一、前言

Meson 是用于自动化构建的自由软件,使用Python语言编写,在 Apache 许可证 2.0版本下发布,主要目标是为了让开发者节约用于配置构建系统的时间。

特点如下:

  • 多平台支持,包括 GNU/Linux、Windows、MacOS、GCC、Clang、Visual Studio等。
  • 多语言支持,包括 C、C++、D、Fortran、Java、Rust等。
  • 构建过程的定义使用对用户非常友好且具有很高可读性的非图灵完备DSL。
  • 为多种操作系统以及裸机提供交叉编译。
  • 针对极其快速和完整的增量构建进行了优化,同时又不牺牲正确性。
  • 类似于 CMake ,Meson 并不直接构建软件,而是使用合适的后端,在 GNU/Linux 使用 ninja,在Windows 上使用 Visual Studio,在 MacOS 上使用 Xcode。

二、安装

1. 使用包管理器安装

在Ubuntu中可执行以下命令进行安装

$ sudo apt-get install python3 python3-pip python3-setuptools \
                       python3-wheel ninja-build

2. 使用Python安装

以用户身份安装

$ pip3 install --user meson

以系统身份安装

$ pip3 install meson

3. 使用安装程序

此处 给出了MSI安装程序用于在Windows上安装Meson和Ninja。

三、简单尝试

1. 控制台 Hello World

Step1 新建 main.c 文件,内容如下:

#include <stdio.h>

int main(int argc, char **argv) {
  printf("Hello World.\n");
  return 0;
}

Step2 新建Meson构建描述文件放在同一目录下的 meson.build 文件中,内容如下:

project('tutorial', 'c')
executable('demo', 'main.c')

Step3 进入源目录,并执行以下命令,进行初始化构建。

$ meson setup builddir

运行 Meson 时,它会打印以下输出:

The Meson build system
 version: 0.13.0-research
Source dir: /home/jpakkane/mesontutorial
Build dir: /home/jpakkane/mesontutorial/builddir
Build type: native build
Project name is "tutorial".
Using native c compiler "ccache cc". (gcc 4.8.2)
Creating build target "demo" with 1 files.

Step4 使用ninja执行构建操作,输入以下命令:

$ cd builddir
$ ninja

或者

$ cd builddir
$ meson compile

Step5 运行构建的可执行文件

$ ./demo

2. 带窗口 Hello World

下面将使用GTK+创建一个带图形窗口的 Hello World .
Step1 新建 main.c 文件,内容如下:

#include <gtk/gtk.h>

//
// Should provided the active view for a GTK application
//
static void activate(GtkApplication* app, gpointer user_data)
{
  GtkWidget *window;
  GtkWidget *label;

  window = gtk_application_window_new (app);
  label = gtk_label_new("Hello World!");
  gtk_container_add (GTK_CONTAINER (window), label);
  gtk_window_set_title(GTK_WINDOW (window), "Welcome to GNOME");
  gtk_window_set_default_size(GTK_WINDOW (window), 400, 200);
  gtk_widget_show_all(window);
} // end of function activate

//
// main is where all program execution starts
//
int main(int argc, char **argv)
{
  GtkApplication *app;
  int status;

  app = gtk_application_new(NULL, G_APPLICATION_FLAGS_NONE);
  g_signal_connect(app, "activate", G_CALLBACK(activate), NULL);
  status = g_application_run(G_APPLICATION(app), argc, argv);
  g_object_unref(app);

  return status;
} // end of function main

Step2 新建Meson构建描述文件放在同一目录下的 meson.build 文件中,内容如下:

project('tutorial', 'c')
gtkdep = dependency('gtk+-3.0')
executable('demo', 'main.c', dependencies : gtkdep)

Step3 进入源目录,并执行以下命令,进行初始化构建。

$ meson setup builddir

运行 Meson 时,它会打印以下输出:

[1/1] Regenerating build files
The Meson build system
 version: 0.13.0-research
Source dir: /home/jpakkane/mesontutorial
Build dir: /home/jpakkane/mesontutorial/builddir
Build type: native build
Project name is "tutorial".
Using native c compiler "ccache cc". (gcc 4.8.2)
Found pkg-config version 0.26.
Dependency gtk+-3.0 found: YES
Creating build target "demo" with 1 files.
[1/2] Compiling c object demo.dir/main.c.o
[2/2] Linking target demo

Step4 使用ninja执行构建操作,输入以下命令:

$ cd builddir
$ ninja

或者

$ cd builddir
$ meson compile

Step5 运行构建的可执行文件

$ ./demo

3. SDL2应用程序

本小节将从头开始展示如何仅使用 Meson 来定义和构建 SDL2 GUI 应用程序。该文档是为 Windows 编写的,因为它是最复杂的平台,但相同的基本思想也适用于 Linux 和 macOS。

Step1 打开VS开发者工具中的 x64 Native Tools Command Prompt
在这里插入图片描述

Step2 进入指定的项目目录
本文在 E:\AAA\SDL_Demo 目录下进行构建,因此进入到此目录下
在这里插入图片描述

Step3 在项目目录下新建文件 sdlprog.c ,内容如下:

#include "SDL.h"

int main(int argc, char *argv[])
{
    SDL_Window *window;
    SDL_Renderer *renderer;
    SDL_Surface *surface;
    SDL_Event event;

    if (SDL_Init(SDL_INIT_VIDEO) < 0) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s", SDL_GetError());
        return 3;
    }

    if (SDL_CreateWindowAndRenderer(320, 240, SDL_WINDOW_RESIZABLE, &window, &renderer)) {
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create window and renderer: %s", SDL_GetError());
        return 3;
    }

    while (1) {
        SDL_PollEvent(&event);
        if (event.type == SDL_QUIT) {
            break;
        }
        SDL_SetRenderDrawColor(renderer, 0x00, 0x00, 0x00, 0x00);
        SDL_RenderClear(renderer);
        SDL_RenderPresent(renderer);
    }

    SDL_DestroyRenderer(renderer);
    SDL_DestroyWindow(window);

    SDL_Quit();

    return 0;
}

Step4 创建 subprojects 目录用于保存外部依赖项

mkdir subprojects

Step5 安装 SDL2 依赖项
Meson 有一个用于下载和构建(如果需要)依赖项的 Web 服务,称为 WrapDB。它提供了SDL2,所以我们可以直接使用它。

meson wrap install sdl2

Step6 新建Meson构建描述文件meson.build

project('sdldemo', 'c',
        default_options: 'default_library=static')

sdl2_dep = dependency('sdl2')

executable('sdlprog', 'sdlprog.c',
           win_subsystem: 'windows',
           dependencies: sdl2_dep)

除了依赖性之外,构建文件这还有一些其他变化。首先,我们指定要静态构建帮助程序库。对于像这样的简单项目,它使事情变得更简单。我们还需要告诉 Meson 我们正在构建的程序是 Windows GUI 应用程序而不是控制台应用程序。

Step7 进入源目录,并执行以下命令,进行初始化构建。

$ meson setup builddir

Step8 使用ninja执行构建操作,输入以下命令:

$ cd builddir
$ ninja

或者

$ cd builddir
$ meson compile

Step9 运行构建的可执行文件

$ ./sdlprog

四、进阶教程

从前面的例子可以看出,不同的编译项目主要区别是 meson.build 文件的编写,下面我们将给出多种情况下的 meson.build 的编写,并给出说明。
注意:meson 的语法与 Python 类似,也使用 # 作为注释标识符。

1. 多文件编译

项目文件结构如下:

├── meson.build
├── main.c
├── foo1.c
└── foo2.c

方式一

project(			# 描述项目相关信息
	'Demo1', 		# 项目名称
	'c'				# 编程语言
)  
executable(			# 编译相关信息
	'demo',  		# 目标程序文件名
	'main.c',	    # 源代码文件
	'foo1.c', 'foo2.c',
)

方式二
meson.build 文件内容如下:

project(			# 描述项目相关信息
	'Demo1', 		# 项目名称
	'c'				# 编程语言
)  
lib = static_library('foo', 'foo1.c', 'foo2.c')  # 其余.c文件
executable(			# 编译相关信息
	'demo',  		# 目标程序文件名
	'main.c',	    # 源代码文件
	link_with:lib 	# 库文件
)

2. 第三方库的使用

项目文件结构如下:

├── meson.build
└── src
		├── include
		│   	└── mylib.h
		├── lib
		│		└── mylib.a
		└── main.c

meson.build 文件内容如下:

project(			# 描述项目相关信息
	'Demo1', 		# 项目名称
	'c'				# 编程语言
) 
# 库文件
libs=meson.get_compiler('c').find_library(
        'static_library',
        dirs : join_paths(meson.source_root(),'src/lib')
)
executable(
    'uselib', 				# 目标程序文件名
    'src/main.c', 			# 源代码文件
    dependencies : libs, 	# 依赖项
    include_directories : 'src/include' # 头文件目录
)

五、可用参数

对于特定命令的所有可用选项,可使用语法:meson COMMAND --help

1. 设置

$ meson setup [-h] [--prefix PREFIX] [--bindir BINDIR] [--datadir DATADIR]
              [--includedir INCLUDEDIR] [--infodir INFODIR]
              [--libdir LIBDIR] [--licensedir LICENSEDIR]
              [--libexecdir LIBEXECDIR] [--localedir LOCALEDIR]
              [--localstatedir LOCALSTATEDIR] [--mandir MANDIR]
              [--sbindir SBINDIR] [--sharedstatedir SHAREDSTATEDIR]
              [--sysconfdir SYSCONFDIR]
              [--auto-features {enabled,disabled,auto}]
              [--backend {ninja,vs,vs2010,vs2012,vs2013,vs2015,vs2017,vs2019,vs2022,xcode,none}]
              [--buildtype {plain,debug,debugoptimized,release,minsize,custom}]
              [--debug] [--default-library {shared,static,both}]
              [--errorlogs] [--install-umask INSTALL_UMASK]
              [--layout {mirror,flat}] [--optimization {plain,0,g,1,2,3,s}]
              [--prefer-static] [--stdsplit] [--strip]
              [--unity {on,off,subprojects}] [--unity-size UNITY_SIZE]
              [--warnlevel {0,1,2,3,everything}] [--werror]
              [--wrap-mode {default,nofallback,nodownload,forcefallback,nopromote}]
              [--force-fallback-for FORCE_FALLBACK_FOR] [--vsenv]
              [--pkgconfig.relocatable]
              [--python.install-env {auto,prefix,system,venv}]
              [--python.platlibdir PYTHON.PLATLIBDIR]
              [--python.purelibdir PYTHON.PURELIBDIR]
              [--pkg-config-path PKG_CONFIG_PATH]
              [--build.pkg-config-path BUILD.PKG_CONFIG_PATH]
              [--cmake-prefix-path CMAKE_PREFIX_PATH]
              [--build.cmake-prefix-path BUILD.CMAKE_PREFIX_PATH]
              [-D option] [--native-file NATIVE_FILE]
              [--cross-file CROSS_FILE] [-v] [--fatal-meson-warnings]
              [--reconfigure] [--wipe]
              [builddir] [sourcedir]

2. 配置

$ meson configure [-h] [--prefix PREFIX] [--bindir BINDIR]
                  [--datadir DATADIR] [--includedir INCLUDEDIR]
                  [--infodir INFODIR] [--libdir LIBDIR]
                  [--licensedir LICENSEDIR] [--libexecdir LIBEXECDIR]
                  [--localedir LOCALEDIR] [--localstatedir LOCALSTATEDIR]
                  [--mandir MANDIR] [--sbindir SBINDIR]
                  [--sharedstatedir SHAREDSTATEDIR]
                  [--sysconfdir SYSCONFDIR]
                  [--auto-features {enabled,disabled,auto}]
                  [--backend {ninja,vs,vs2010,vs2012,vs2013,vs2015,vs2017,vs2019,vs2022,xcode,none}]
                  [--buildtype {plain,debug,debugoptimized,release,minsize,custom}]
                  [--debug] [--default-library {shared,static,both}]
                  [--errorlogs] [--install-umask INSTALL_UMASK]
                  [--layout {mirror,flat}]
                  [--optimization {plain,0,g,1,2,3,s}] [--prefer-static]
                  [--stdsplit] [--strip] [--unity {on,off,subprojects}]
                  [--unity-size UNITY_SIZE]
                  [--warnlevel {0,1,2,3,everything}] [--werror]
                  [--wrap-mode {default,nofallback,nodownload,forcefallback,nopromote}]
                  [--force-fallback-for FORCE_FALLBACK_FOR] [--vsenv]
                  [--pkgconfig.relocatable]
                  [--python.install-env {auto,prefix,system,venv}]
                  [--python.platlibdir PYTHON.PLATLIBDIR]
                  [--python.purelibdir PYTHON.PURELIBDIR]
                  [--pkg-config-path PKG_CONFIG_PATH]
                  [--build.pkg-config-path BUILD.PKG_CONFIG_PATH]
                  [--cmake-prefix-path CMAKE_PREFIX_PATH]
                  [--build.cmake-prefix-path BUILD.CMAKE_PREFIX_PATH]
                  [-D option] [--clearcache] [--no-pager]
                  [builddir]

3. 编译

$ meson compile [-h] [--clean] [-C WD] [-j JOBS] [-l LOAD_AVERAGE] [-v]
                [--ninja-args NINJA_ARGS] [--vs-args VS_ARGS]
                [--xcode-args XCODE_ARGS]
                [TARGET ...]


👇 👇 👇 👇 👇 👇 👇 👇 👇 👇 👇 👇 👇 👇 👇 👇 👇 👇 👇 👇 👇 👇 👇 👇 👇 👇 👇 👇

如果觉得本文有所帮助,还请 点赞、收藏、关注 ,您的支持是我持续更新的动力。

👆 👆 👆 👆 👆 👆 👆 👆 👆 👆 👆 👆 👆 👆 👆 👆 👆 👆 👆 👆 👆 👆 👆 👆 👆 👆 👆 👆

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值