理解 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中的钩子由pip或pypa/build等构建前端调用的东西)。这是 Meson 之上的一个薄层,主要作用是(a)与构建前端接口,以及(b)生成具有有效文件名和元数据的 sdist 和 wheel。
警告
截至 2023 年 12 月,NumPy 会捆绑一个自定义版本的 Meson,这对于上游 Meson 尚未提供的 SIMD 和 BLAS/LAPACK 功能是必需的。因此,不能直接使用 meson 可执行文件。相反,无论何时说明中出现 meson xxx,都应使用 python vendored-meson/meson/meson.py xxx 代替。
使用 Meson 构建分为几个阶段
配置阶段(
meson setup),用于检测编译器、依赖项和构建选项,并创建构建目录和build.ninja文件,编译阶段(
meson compile或ninja),其中构建的 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 版本),并且在其他平台上最多只有适度数量的警告。