理解 Meson#

构建 NumPy 依赖于以下工具,这些工具可以被视为构建系统的一部分:

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

  • 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) 生成具有有效文件名和元数据的源代码包和 wheel 包.

警告

截至23年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”问题的最佳来源.此外,还可以在 https://nibblestew.blogspot.com/2021/12/this-year-receive-gift-of-free-meson.html 免费获取一本关于 Meson 的详尽pdf书籍.

要了解更多关于 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 版本),并且在其他平台上最多有适量的警告.