AI Summary 146.20565.2 Meson摘要 2026-10-10
Meson 定位是 CMake 用的是 Ninja 对应 GNU Make

Meson

为什么要放着好的 CMake 不用 而来用 Meson

因为 Meson 足够简单 比起冗长的 CMakeLists.txt

meson.build 要更加易读

许多的 Linux 项目都是使用 Meson

特别是 Gnome 和 GTK 的项目

https://github.com/mesonbuild/meson/releases/download/1.12.1/meson-1.12.1.tar.gz

使用 pip 安装 Meson

Meson 可在 Python 包索引 中获得

用

pip3 install --user meson

安装。这不需要任何特殊权限

~/.local/

中安装软件包,因此你必须将

~/.local/bin

添加到你的 PATH 中

如果你仅将 Meson 用于本地开发 这应该是你需要的全部操作

入门示例 编译一个单文件项目,其目录结构如下

.

├── main.cpp

└── meson.build

其中 meson.build 内容如下

project('meson tutorial', 'cpp')

executable('tutorial', 'main.cpp')

初始化

要使用 Meson 来构建项目

首先要使用 Meson 来初始化

meson setup --prefix="$HOME/.local/sdk/user" --backend="ninja" --buildtype="debug" "./build/debug" "./"

其中

--prefix 指定了软件安装位置

--backend 指定了底层编译工具

--buildtype 指定了编译类型,是调试类型还是发行类型

而如果要优化编译,可以使用发行类型

meson setup --prefix="$HOME/.local/sdk/user" --backend="ninja" --buildtype="release" --debug "./build/release" "./"

这些选项都可以忽略

默认情况的安装位置是 /local/usr

而编译类型则默认是调试类型 所以一般来说可以简化为如下指令

meson setup "./build/debug" "./"

后面两个是位置参数

分别代表编译到的位置以及源代码所在目录

更为直接的,可以使用

meson build

来初始化项目, 默认编译内容会放到

./build

目录下 但是为了方便区分,一般还是会放到类似 ./build/debug 这种目录下

编译

初始化项目后就是要编译项目

meson compile -C "./build/debug"

其中

-C 表示执行编译指令前先切换到对应目录

这是因为 meson compile 只有在 Meson Build 目录下才能编译

也可与手动使用对应的编译后端来编译,例如 ninja

ninja -C "./build/debug"

正常项目的结构

.

├── include

│ ├── meson.build

│ └── tut

│ └── tut.hpp

├── meson.build

├── src

│ ├── main.cpp

│ ├── meson.build

│ └── tut

│ ├── meson.build

│ └── tut.cpp

└── subprojects

└── libtutorial

├── include

│ ├── meson.build

│ └── tutorial

│ └── tutorial.hpp

├── meson.build

└── tutorial.cpp

其中 tut 是项目内部库

而 libtutorial 则是子项目,可以是用源码管理的外部项目

自顶向下来看看每个 meson.build 文件里写了什么,以及各自的作用

项目配置

# ./meson.build

project(

'example',

'cpp',

version: '0.1',

default_options: ['cpp_std=c++17'],

)

# headers

subdir('include')

incs = include_directories('include')

# subprojects

libtutorial_dep = dependency('libtutorial', fallback: ['libtutorial', 'libtutorial_dep'])

# sources

subdir('src')

executable(

'example',

sources,

include_directories: incs,

dependencies: [libtutorial_dep, libtut_dep],

install: true,

)

在 project() 中,

可以设置非常多的东西,例如项目的版本,使用的语言,以及标准等级

通过 subdir() 将 include 目录加入项目,

这是一个推荐做法,也就是将头文件专门用一个目录存放,

而不是和源码放在一起,

方便 pkgconfig 之类的工具安装库和设置对应变量

include_directories() 则是为了生成 compile_commands.json 文件,方便 IDE 提示

对于外部依赖,如果是通过源码管理的,

可以使用 subproject() 来加入依赖,

但是由于需求非常常见,所以我们可以直接使用 dependency() 的 fallback 选项快捷地添加依赖

而后就是将源文件目录加入项目,通过 executable() 从而编译生成一个可执行文件

头文件管理

在 include 目录中,文件内容如下:

# ./include/meson.build

install_subdir('tut', install_dir: get_option('includedir'))

而在 subprojects/libtutorial/include 文件夹中的内容大同小异,只是将目录名改成了 tutorial

install_subdir() 指定了要安装的头文件,方便之后寻找头文件

源码管理

这里源码分成了两部分,一个是可执行文件对应的 main.cpp,另一个就是项目自己的库 tut

# ./src/meson.build

# all source file for executable

sources = files('main.cpp')

# local libs

subdir('tut')

内容非常简单,通过 files 指定有哪些文件,然后在 ./meson.build 中就可以通过 sources 变量来使用这些文件,然后将 tut 加入项目

# ./src/tut/meson.build

# sources

tut_sources = files('tut.cpp')

# math dependency

cxx = meson.get_compiler('cpp')

m_dep = cxx.find_library('m', required: true)

# declare a shared library

# can use static_library() for static libraries

# or just use library() and declare by options

libtut = shared_library(

'tut',

tut_sources,

include_directories: incs,

dependencies: [m_dep],

install: true,

)

# declare as a dependency

libtut_dep = declare_dependency(include_directories: incs, link_with: libtut)

# generate pkgconfig files

pkg_config = import('pkgconfig')

pkg_config.generate(

name: 'Tut',

filebase: 'tut',

description: 'a meson tutorial dependcies',

libraries: libtut,

)

在 tut 中

定义了一个库,库的定义一般使用 library()

但是如果要指定库的形式,那么也可以使用 static_library() 和 shared_library() 来指定

编译器有时候并不会自动链接一些库,例如数学库 m 和线程库,

需要通过编译器来链接对应的库依赖,即 cxx.find_library(), 其中 required 选项如果是 true,那么在找不到库的情况下编译过程就会停止,而 false 则不会

为了方便别人链接我们的库,

可以自己暴露一些变量,例如 libtut_dep,

而其他人就可以通过 get_variable() 来获取这些内容

如果要更进一步使用 pkgconfig 管理,

使用 import 加载 pkgconfig 的相关内容, 然后通过 generate 为我们的库生成对应的 .pc 文件

子项目

子项目一定要放在 ./subprojects 文件夹下,而 ./subprojects/libtutorial/meson.build 文件则是项目文件,也就是需要有 project()

# ./subprojects/libtutorial/meson.build

# library project declare

project('libtutorial', 'cpp', default_options: ['cpp_std=c++17'])

# headers

subdir('include')

headers = include_directories('include')

# sources

sources = files('tutorial.cpp')

# declare a static library

# can use shared_library() for shared libraries

# or just use library() and declare by options

libtutorial = static_library(

'tutorial',

sources,

include_directories: headers,

install: true,

)

# declare as a dependency

libtutorial_dep = declare_dependency(include_directories: headers, link_with: libtutorial)

# generate pkgconfig files

pkg_config = import('pkgconfig')

pkg_config.generate(

name: 'Tutorial',

filebase: 'tutorial',

description: 'a meson tutorial subproject',

libraries: libtutorial,

)

编译和安装

准备好这些文件后,我们就可以开始编译了,初始化过程和普通项目一样,编译可以使用 meson compile -C "./build/debug" 来编译

meson setup --prefix="$HOME/.local/sdk/user" --backend="ninja" --buildtype="debug" "./build/debug" "./"

meson compile -C "./build/debug"

meson install -C "./build/debug"

后记

Meson 看起来比较繁琐,但是功能上比较直观,并且非常方便配合 pkgconfig 工具使用,所以还是非常值得一学的