Meson 构建系统入门与实战教程(面向 Python C++ 扩展开发)
适用于希望用 Meson + pybind11 编译 Python C/C++ 扩展(如量化交易接口、高性能计算模块等)的开发者。
一、什么是 Meson?
Meson 是一个快速、用户友好的现代构建系统,专为 C/C++/Python 等语言设计。它使用 Ninja 作为默认后端,构建速度极快,语法简洁(类似 Python),特别适合:
- 编译 pybind11 / Cython 的 Python 扩展
- 跨平台项目(Windows / Linux / macOS)
- 大型 C++ 项目
✅ 优势:比 CMake 更简洁,比 Makefile 更安全,比 setuptools 更强大。
二、安装 Meson
前提:已安装 Python 和 pip
# 安装 Meson 和 Ninja(推荐方式) pip install meson ninja # 验证安装 meson --version # 如 1.5.0 ninja --version # 如 1.11.1💡 Windows 用户还需安装 Visual Studio 2019+(含 C++ 桌面开发工具)
Linux 用户需安装build-essential(Ubuntu)或gcc-c++(CentOS)
macOS 用户需安装 Xcode Command Line Tools:xcode-select --install
三、Meson 核心概念
| 概念 | 说明 |
|---|---|
meson.build | 项目构建脚本(必须放在项目根目录) |
project() | 声明项目名称、语言、版本 |
dependency() | 查找外部依赖(如 pybind11、OpenCV) |
shared_module() | 生成 Python 扩展模块(.so / .pyd) |
builddir | 构建输出目录(必须 out-of-source) |
四、Hello World:编译一个 pybind11 扩展
步骤 1:创建项目结构
myproject/ ├── meson.build # ← 构建脚本 └── src/ └── module.cpp # ← C++ 源码步骤 2:编写 C++ 代码 (src/module.cpp)
#include<pybind11/pybind11.h>intadd(int a,int b){return a + b;}PYBIND11_MODULE(mymodule, m){ m.doc()="A simple pybind11 example"; m.def("add",&add,"Add two numbers");}步骤 3:编写 meson.build
# 声明项目 project('myproject', 'cpp', version: '1.0.0') # 查找 pybind11 依赖 pybind11_dep = dependency('pybind11') # 定义源文件 sources = ['src/module.cpp'] # 生成 Python 扩展模块 # 注意:模块名必须与 PYBIND11_MODULE 中一致 shared_module('mymodule', sources, dependencies: pybind11_dep, name_prefix: '', # 避免加 lib 前缀 name_suffix: 'pyd' if host_machine.system() == 'windows' else 'so') 步骤 4:编译
# 需要重新编译时删除rm -r builddir # 创建构建目录(必须!) meson setup builddir # 编译 meson compile -C builddir 步骤 5:测试
# 复制 .so/.pyd 到当前目录cp builddir/mymodule.* ./ # 启动 Python 测试 python -c "import mymodule; print(mymodule.add(2, 3))"# 输出 5五、进阶:链接第三方库(以 CTP 为例)
假设你有 CTP SDK:
- 头文件:
ctp/include/ThostFtdcUserApi.h - 库文件:
ctp/lib/thosttraderapi.lib(Windows)或libthosttraderapi.so(Linux)
meson.build 示例
project('vnctptd', 'cpp', default_options: ['cpp_std=c++17']) pybind11_dep = dependency('pybind11') ctp_inc = include_directories('ctp/include') # 源文件 sources = ['api/vnctptd.cpp'] # 处理不同平台的库 if host_machine.system() == 'windows' ctp_lib = 'thosttraderapi' # 无需 .lib 后缀 suffix = 'pyd' else ctp_lib = declare_dependency( link_args: ['-Lctp/lib', '-lthosttraderapi'] ) suffix = 'so' endif # 构建模块 td_module = shared_module('_vnctptd', sources, include_directories: ctp_inc, dependencies: pybind11_dep, name_prefix: '', name_suffix: suffix) # Windows 需要显式链接 if host_machine.system() == 'windows' target_link_libraries(td_module, ctp_lib) endif ⚠️ 注意:Windows 下.lib文件需在链接路径中(如放在项目根目录或ctp/lib/)Linux/macOS 需确保.so/.dylib在运行时可找到(LD_LIBRARY_PATH或@rpath)
六、常用命令速查
| 命令 | 作用 |
|---|---|
meson setup builddir | 初始化构建目录 |
meson compile -C builddir | 编译项目 |
meson test -C builddir | 运行测试(如果定义了) |
meson install -C builddir | 安装到指定目录 |
meson configure -C builddir -Dbuildtype=release | 设置构建类型 |
构建类型
debug(默认)releaseplain(无调试符号,无优化)
七、与 Python 生态集成(PEP 517)
要让项目支持 pip install .,需创建 pyproject.toml:
[build-system] requires = ["scikit-build-core", "pybind11"] build-backend = "scikit_build_core.build" [project] name = "myproject" version = "1.0.0" 然后:
pip install.✅ scikit-build-core 会自动调用 Meson 编译扩展。八、常见问题解决
❌ 问题1:Dependency "pybind11" not found
- 原因:未安装 pybind11
- 解决:
pip install pybind11
❌ 问题2:undefined reference to ...
- 原因:未正确链接第三方库
- 解决:
- Windows:确保
.lib在链接路径 - Linux:用
declare_dependency(link_args: [...])
- Windows:确保
❌ 问题3:模块导入时报错 ImportError: DLL load failed
- 原因:缺少运行时依赖(如 CTP 的
.dll) - 解决:
- Windows:将
thosttraderapi.dll放在.pyd同目录 - Linux:设置
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
- Windows:将
九、学习资源
| 资源 | 链接 |
|---|---|
| 官方文档 | https://mesonbuild.com/ |
| Python 扩展示例 | https://mesonbuild.com/Python-module.html |
| pybind11 + Meson | https://github.com/pybind/pybind11/tree/stable/example/meson |
| vn.py CTP 插件 | https://gitee.com/vnpy/vnpy_ctp |
✅ 总结
| 场景 | 推荐方案 |
|---|---|
| 简单 Python C++ 扩展 | Meson + pybind11(比 CMake 更简洁) |
| 大型跨平台 C++ 项目 | Meson(构建速度更快) |
| 需要 pip 安装 | Meson + scikit-build-core(现代标准) |
💡 记住:Meson 的核心是meson.build手写 + out-of-source 构建。掌握shared_module()和dependency(),你就能编译任何 Python 扩展!