Создание распространяемых двоичных файлов#

Целевая аудитория этого раздела — все, кто хочет собрать SciPy и развернуть его где-либо, кроме собственной машины — от упаковщиков дистрибутивов до пользователей, которые хотят собрать wheels для развёртывания в своей производственной среде

Когда python -m build или pip wheel используется для сборки колеса SciPy, это колесо будет зависеть от внешних общих библиотек (по крайней мере для BLAS/LAPACK и библиотеки времени выполнения компилятора Fortran, возможно других библиотек). Такие колеса поэтому будут работать только на системе, на которой они собраны. См. содержимое pypackaging-native в разделе «Сборка и установка или загрузка артефактов» для получения дополнительного контекста.

Такой wheel является промежуточным этапом для создания бинарного файла, который можно распространять. Этот конечный бинарный файл может быть wheel - в этом случае запустите auditwheel (Linux), delocate (macOS), delvewheel (Windows) или repairwheel (независимо от платформы) для включения необходимых общих библиотек в колесо.

Финальный бинарный файл также может быть в другом формате упаковки (например, .rpm, .deb или .conda пакет). В этом случае существуют инструменты, специфичные для экосистемы упаковки, чтобы сначала установить wheel в промежуточную область, затем сделать модули расширения в этом месте установки перемещаемыми (например, переписав RPATH), а затем переупаковать их в окончательный формат пакета.

Зависимости сборки и выполнения#

Зависимости сборки и выполнения Python, необходимые для сборки SciPy, можно найти в pyproject.toml метаданные. Обратите внимание, что для выпущенных версий SciPy зависимости, вероятно, будут иметь верхние границы. Каждая верхняя граница имеет комментарии выше; упаковщики могут свободно удалять или ослаблять эти верхние границы в большинстве случаев (кроме numpy). Например:

# The upper bound on pybind11 is preemptive only
"pybind11>=2.12.0,<2.13.0",

#   ...
#   3. The <2.3 upper bound is for matching the numpy deprecation policy,
#      it should not be loosened.
"numpy>=2.0.0rc1,<2.3",

Не-Python требования для сборки:

  • Компиляторы C, C++ и Fortran

  • Библиотеки BLAS и LAPACK

  • ninja

  • pkg-config

Возможность использования ключевых слов '3-point', 'cs' с методом 'lm'. Ранее 'lm' был ограничен '2-point' и вызываемыми объектами. meson.build файл. Минимальная версия LAPACK в настоящее время 3.7.1. Более подробную информацию об этих зависимостях сборки можно найти в Дорожная карта инструментария.

Использование системных зависимостей вместо вендорных источников#

SciPy содержит много кода, который был взят из библиотек, написанных на C, C++ и Fortran. Это сделано по смеси исторических и надёжностных причин. Создатели дистрибутивов иногда имеют причины, чтобы развендорить этот код, гарантируя, что у них используется только одна версия конкретной библиотеки. Мы предлагаем опцию сборки, -Duse-system-libraries, чтобы позволить им делать это гораздо проще, чем можно сделать вручную патчами SciPy.

$ python -m build -wnx -Duse-system-libraries=boost.math

Эта опция сборки вызывает поиск зависимостей для точно такой же версии как включено только в SciPy. Другая системная версия не будет принята, сборка тогда переключится на встроенные исходники или завершится ошибкой. Это связано с тем, что разные версии могут легко вызывать сбои во время сборки или выполнения, и CI SciPy не тестирует с другими версиями. Это может измениться в будущем, однако на данный момент использование другой версии требует исправления соответствующей проверки версии и настоятельно не рекомендуется.

Рекомендации для упаковщиков:

  1. Следует рассматривать эту опцию сборки как «если я уже отделяю библиотеку по веской причине, эта опция значительно упрощает этот процесс».

  2. Не следует по умолчанию отвязывать всё, это вызовет ромбовидные зависимости и увеличит сложность сборки при малой выгоде. Большинство этих библиотек не поддерживаются так же хорошо, как SciPy, и/или известно, что они не предлагают стабильный API; по сути, вы добавите лишний == зависимость для каждой библиотеки, которую вы выносите. Делайте это только по веской причине. Например, это позволяет вам убрать патчи, вы считаете как SciPy, так и включенную библиотеку критически важными для безопасности, или это дает значительный выигрыш в размере бинарного файла.

Опция сборки принимает следующие значения:

  • none: Использовать исходный код, поставляемый в составе SciPy, не искать внешние зависимости (по умолчанию).

  • all: Использовать внешние библиотеки для всех компонентов, управляемых use-system-libraries, и выдать ошибку, если они не найдены. Обнаружение выполняется Meson, обычно сначала через pkg-config и затем cmake метод dependency() функция.

  • auto: Попробовать обнаружить внешние библиотеки, и если они не найдены, то переключиться на встроенные источники.

  • Список имён зависимостей, разделённых запятыми (например, boost.math,qhull). Если задан, использует all поведение для указанных зависимостей (и none для остальных). Поддерживаемые опции:

    • boost.math (с версии 1.16.0)

    • qhull (с версии 1.16.0)

Также допустимо комбинировать общие и именованные библиотечные опции выше, например boost.math,auto применит auto поведение для всех зависимостей, кроме boost.math.

Удаление тестового набора из wheel или установленного пакета#

По умолчанию установленная версия scipy включает полный набор тестов. Этот набор тестов, включая файлы данных и скомпилированные модули расширений, которые используются только для тестирования, занимает около 4,5 МБ в колесе (для x86-64, по состоянию на v1.14.0), и больше этого на диске. В случаях, когда размер бинарного файла имеет значение, упаковщики могут захотеть удалить набор тестов. Начиная с SciPy 1.14.0, существует удобный способ сделать это, используя Теги установки Meson функциональность. Это однострочник:

$ python -m build -wnx -Cinstall-args=--tags=runtime,python-runtime,devel

Примечание

Обратите внимание, что в приведенной выше команде -wnx средние значения --wheel --no-isolation --skip-dependency-check. Предполагается, что упаковщик уже настроил среду сборки, что обычно верно для дистрибутивной упаковки. Функция установочных тегов одинаково хорошо работает с изолированными сборками (например, pip install scipy --no-binary -Cinstall-args=--tags=runtime,python-runtime,devel).

Если вы хотите создать отдельный пакет для самих тестов, например, под именем scipy-tests, затем редактировать pyproject.toml изменить название проекта:

[project]
name = "scipy-tests"

А затем собрать с помощью:

$ python -m build -wnx -Cinstall-args=--tags=tests

Вышеописанное построит весь пакет дважды; чтобы перестроить с использованием кэша, используйте -Cbuild-dir=build опция сборки:

$     $ # apply patch to change the project name in pyproject.toml
$ python -m build -wnx -Cbuild-dir=build -Cinstall-args=--tags=tests

Конечный результат будет выглядеть примерно так:

$ ls -lh dist/*.whl
...  20M  ...  dist/scipy-1.14.0-cp311-cp311-linux_x86_64.whl
...  4,5M ...  dist/scipy_tests-1.14.0-cp311-cp311-linux_x86_64.whl