理解 Meson#
构建 SciPy 依赖于以下工具,这些工具可以被视为构建系统的一部分:
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
中的钩子被pip
或pypa/build
等构建前端调用的部分)。这是 Meson 之上的一个薄层,主要角色是 (a) 与构建前端接口,以及 (b) 生成具有有效文件名和元数据的源代码分发包和轮子。
使用 Meson 构建分为几个阶段:
配置阶段 (
meson setup
) 用于检测编译器、依赖项和构建选项,并创建构建目录和build.ninja
文件。编译阶段(
meson compile
或ninja
),在此阶段,作为构建的 SciPy 包一部分的扩展模块被编译。安装阶段 (
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 上链接的最近演讲也是一个很好的资源。
构建阶段的解释#
这只是为了教学目的;不需要单独执行这些阶段。仓库根目录中的 dev.py 脚本也包含这些步骤,可以研究以获得见解。
假设我们从一个干净的仓库和一个完全配置好的 conda 环境开始:
git clone git@github.com:scipy/scipy.git
git submodule update --init
mamba env create -f environment.yml
mamba activate scipy-dev
现在要运行构建的配置阶段,并指示 Meson 将构建工件放在 build/
中,并在相对于仓库根目录的 build-install/
下进行本地安装,请执行:
meson setup build --prefix=$PWD/build-install
要运行构建的编译阶段,请执行:
ninja -C build
在上面的命令中,-C
后面跟着的是构建目录的名称。你可以同时拥有多个构建目录。Meson是完全独立于源代码的,因此这些构建不会相互干扰。例如,你可以在不同的目录中拥有一个GCC构建、一个Clang构建和一个调试构建。
然后,将 SciPy 安装到前缀(此处为 build-install/
,但请注意,这只是我们在此处选择的任意名称):
meson install -C build
然后它将安装到 build-install/lib/python3.11/site-packages/scipy
,这不在你的 Python 路径中,所以为了添加它,请执行以下操作(再次强调,这是为了学习目的,通常不建议显式使用 ``PYTHONPATH``):
export PYTHONPATH=$PWD/build-install/lib/python3.11/site-packages/
现在我们应该能够导入 scipy
并运行测试。记住我们需要从仓库的根目录移出,以确保我们选择的是包而不是本地的 scipy/
源目录:
cd doc
python -c "from scipy import constants as s; s.test()"
上述命令运行了单个模块 constants
的测试。其他运行测试的方法也应该有效,例如:
pytest --pyargs scipy
完整的测试套件应该通过,在Linux上(至少在使用GCC版本时,CI中强制执行``-Werror``)没有任何构建警告,并且在其他平台上最多有适度的警告。