理解 Meson#

构建 NumPy 依赖于以下工具,它们可以被认为是构建系统的一部分

  • meson: Meson 构建系统,可作为纯 Python 包从 PyPI 或 conda-forge 安装

  • ninja: Meson 调用以执行实际构建(例如调用编译器)的构建工具。也可从 PyPI(在所有常见平台上)或 conda-forge 安装。

  • pkg-config: 用于发现依赖项(特别是 BLAS/LAPACK)的工具。可在 conda-forge(以及 Homebrew、Chocolatey 和 Linux 包管理器)上获取,但未在 PyPI 上打包。

  • meson-python: Python 构建后端(即,通过 pyproject.toml 中的钩子被 pippypa/build 等构建前端调用的东西)。这是 Meson 上的一个薄层,主要作用是 (a) 与构建前端交互,以及 (b) 生成带有有效文件名和元数据的 sdist 和 wheel。

警告

截至 2023 年 12 月,NumPy 附带了一个定制版本的 Meson,这是 SIMD 和 BLAS/LAPACK 功能所必需的,这些功能尚未在 Meson 上游版本中提供。因此,不能直接使用 meson 可执行文件。相反,在说明中凡是出现 meson xxx 的地方,请改用 python vendored-meson/meson/meson.py xxx

使用 Meson 构建分阶段进行

  • 配置阶段(meson setup)用于检测编译器、依赖项和构建选项,并创建构建目录和 build.ninja 文件,

  • 编译阶段(meson compileninja),在此阶段编译已构建 NumPy 包中的扩展模块,

  • 安装阶段(meson install)用于将源目录和构建目录中可安装的文件安装到目标安装目录,

Meson 有一个良好的构建依赖跟踪系统,因此第二次调用构建将仅重新构建其任何源或依赖项已更改的目标。

了解更多关于 Meson#

Meson 拥有非常好的文档;阅读它会很有帮助,而且通常是“如何做 X”的最佳答案来源。此外,一本关于 Meson 的完整 PDF 书籍可从 https://nibblestew.blogspot.com/2021/12/this-year-receive-gift-of-free-meson.html 免费获取。

要了解更多关于 Meson 使用的设计原则,可以参考 mesonbuild.com/Videos 中链接的近期演讲,它们也是很好的资源。

构建阶段说明#

这仅用于教学目的;没有必要单独执行这些阶段!

假设我们从一个干净的仓库和一个完全设置好的 conda 环境开始

git clone git@github.com:numpy/numpy.git
git submodule update --init
mamba env create -f environment.yml
mamba activate numpy-dev

现在运行构建的配置阶段,并指示 Meson 将构建产物放在 build/ 下,并将本地安装放在相对于仓库根目录的 build-install/ 下,操作如下

meson setup build --prefix=$PWD/build-install

然后运行构建的编译阶段,操作如下

ninja -C build

在上述命令中,-C 后面跟着构建目录的名称。你可以同时拥有多个构建目录。Meson 完全是异地构建的,所以这些构建不会相互干扰。例如,你可以在不同的目录中进行 GCC 构建、Clang 构建和调试构建。

然后将 NumPy 安装到前缀(这里是 build-install/,但请注意这只是我们此处选择的任意名称)

meson install -C build

它将安装到 build-install/lib/python3.11/site-packages/numpy,这不在你的 Python 路径上,所以要添加它,请执行(再次强调,这是出于学习目的,明确使用 PYTHONPATH 通常不是最好的主意

export PYTHONPATH=$PWD/build-install/lib/python3.11/site-packages/

现在我们应该能够导入 numpy 并运行测试。请记住,我们需要移出仓库根目录以确保我们使用的是包而不是本地的 numpy/ 源目录

cd doc
python -c "import numpy as np; np.test()"

上述命令运行 NumPy 的“快速”测试套件。其他运行测试的方式也应该有效,例如

pytest --pyargs numpy

完整的测试套件应该通过,在 Linux 上不应有任何构建警告(至少在 CI 中强制执行 -Werror 的 GCC 版本下),在其他平台上最多只有少量警告。