理解 Meson#

建置 SciPy 依賴於以下工具,這些工具可以視為建置系統的一部分

  • 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 中的 hook 由建置前端(如 pippypa/build)呼叫的東西)。這是 Meson 之上的薄層,主要作用是 (a) 與建置前端介面,以及 (b) 產生具有有效檔名和元資料的 sdist 和 wheel。

使用 Meson 建置分為多個階段

  • 設定階段 (meson setup) 以偵測編譯器、依賴項和建置選項,並建立建置目錄和 build.ninja 檔案,

  • 編譯階段 (meson compileninja),其中作為已建置 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 連結中的近期演講也是很好的資源。

建置階段說明#

這僅用於教學目的;應該不需要單獨執行這些階段。 repo 根目錄中的 dev.py 腳本也包含這些步驟,可以研究以獲得深入了解。

假設我們從乾淨的 repo 和完全設定好的 conda 環境開始

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

現在執行建置的設定階段,並指示 Meson 將建置產物放在相對於 repo 根目錄的 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 並執行測試。請記住,我們需要移出 repo 的根目錄,以確保我們選取套件而不是本地 scipy/ 原始碼目錄

cd doc
python -c "from scipy import constants as s; s.test()"

上述命令為單一模組 constants 執行測試。其他執行測試的方式也應該有效,例如

pytest --pyargs scipy

完整的測試套件應該通過,在 Linux 上沒有任何建置警告(至少對於在 CI 中強制執行 -Werror 的 GCC 版本),並且在其他平台上最多只有適量的警告。