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(默认)
  • release
  • plain(无调试符号,无优化)

七、与 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: [...])

❌ 问题3:模块导入时报错 ImportError: DLL load failed

  • 原因:缺少运行时依赖(如 CTP 的 .dll
  • 解决
    • Windows:将 thosttraderapi.dll 放在 .pyd 同目录
    • Linux:设置 export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH

九、学习资源

资源链接
官方文档https://mesonbuild.com/
Python 扩展示例https://mesonbuild.com/Python-module.html
pybind11 + Mesonhttps://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 扩展!

Read more

【C++】类和对象—(下) 收官之战

【C++】类和对象—(下) 收官之战

前言:上一篇文章我们向大家介绍了类和对象的核心六个成员函数中的4个,其余两个以及初始化列表,static成员,内部类,匿名对象等会在本篇文章介绍! ✨ 坚持用清晰易懂的图解+代码语言, 让每个知识点都简单直观! 🚀 个人主页 :MSTcheng · ZEEKLOG 🌱 代码仓库 :MSTcheng · Gitee 📌 专栏系列 :📖 《C语言》🧩 《数据结构》💡 《C++由浅入深》💬 座右铭 :“路虽远行则将至,事虽难做则必成!” 文章目录 * 一,运算符重载 * 1.1什么是运算符重载? * 1.2 为什么要创造运算符重载? * 二,赋值运算符重载 * 2.1赋值运算符重载的构成 * 2.1 >>流插入<<流提取重载 * 3.1const成员函数 * 4.1取地址运算符重载 * 三,初始化列表 * 3.

By Ne0inhk
特殊类的设计----《Hello C++ Wrold!》(28)--(C/C++)

特殊类的设计----《Hello C++ Wrold!》(28)--(C/C++)

文章目录 * 前言 * 设计一个不能被拷贝的类 * 设计一个只能在堆上创建对象的类 * 设计一个只能在栈上创建对象的类 * 设计一个不能被继承的类 * 设计一个只能创建一个对象的类(也叫做单例模式) * 单例模式的两种实现方法 * 饿汉模式 * 懒汉模式 前言 在 C++ 面向对象编程体系中,类是封装数据与行为的核心单元,其设计直接关系到程序的安全性、可维护性与性能表现。除了支撑常规业务逻辑的普通类,实际开发中常需面对具有特殊约束的场景:例如防止对象拷贝以规避资源重复释放风险,限定对象创建位置(仅堆或仅栈)以规范内存管理,禁止类被继承以保障核心逻辑不被篡改,或是确保类仅存在一个实例以实现全局资源统一调度 —— 这些需求的实现,正是特殊类设计的核心范畴。 本文聚焦 “特殊类设计” 这一主题,系统拆解五种典型特殊类的实现逻辑与技术细节。从 “不能被拷贝的类” 对拷贝构造函数、赋值运算符的管控,到 “只能在堆 / 栈上创建对象的类” 对构造函数与内存分配接口的限制;从 “不能被继承的类” 基于构造函数私有化(C++98)与final关键字(

By Ne0inhk

C++ string(初识)

目录 初识string 初始化: 核心基础(std::string 常用基本操作): 获取字符串长度 访问单个字符 字符串拼接 修改字符串 判断字符串是否为空 注意事项: string 常用接口 string类的成员函数: constructior  构造函数: destructor   析构函数 operator=  赋值 迭代器: 容量: 额外解释reserve:: resize std::string不是 C++ 内置数据类型,而是标准库提供的模板类(准确说是 std::basic_string<char> 的别名),它封装了字符串的存储和各种操作,无需你手动管理内存(比如扩容、释放),是处理字符串的首选。 使用它的前置条件: 1. 必须包含头文件 <string>

By Ne0inhk
C++ 异常完全指南:从语法到实战,优雅处理程序错误

C++ 异常完全指南:从语法到实战,优雅处理程序错误

🔥草莓熊Lotso: ❄️个人专栏: ✨生活是默默的坚持,毅力是永久的享受! 🎬 博主简介: 文章目录 * 前言: * 一. 异常的核心概念与基本语法\ * 1.1 异常的核心思想 * 1.2 基础语法格式和最简示例 * 二. 异常的核心机制:栈展开与匹配规则 * 2.1 栈展开 * 2.2 异常捕获的匹配规则 * 三. 自定义异常体系:大型项目的最佳实践 * 3.1 自定义异常体系设计 && 异常抛出与捕获实战 * 四. 异常的高级用法 * 4.1 异常重新抛出 * 4.2 异常安全:避免资源泄漏 * 4.3 异常规范( noexcept ) * 五. C++ 标准库异常体系 * 结尾:

By Ne0inhk