Spec-Zone.ru › Python 3.10

Создание собственных дистрибутивов

Примечание

Этот документ сохраняется только до тех пор, пока документация setuptools по адресу https://setuptools.readthedocs.io/en/latest/setuptools.html самостоятельно не охватить всю релевантную информацию, которая в настоящее время включена здесь.

«Собственный дистрибутив» — это то, что вы, вероятно, привыкли представлять как «бинарный пакет» или «инсталлятор» (в зависимости от вашего опыта). Однако он не обязательно является бинарным, так как может содержать только исходный код Python и/или байткод; и мы не называем его пакетом, так как это слово уже используется в Python. (А «инсталлятор» — это термин, специфичный для мира основных настольных систем.)

Собственный дистрибутив – это способ максимально упростить работу для инсталляторов вашего модульного дистрибутива: для пользователей систем Linux на основе RPM – это бинарный RPM; для пользователей Windows – это инсталлятор в виде исполняемого файла; для пользователей Linux на основе Debian – это пакет Debian; и так далее. Очевидно, что ни один человек не сможет создать собственные дистрибутивы для каждой платформы, поэтому утилиты Distutils разработаны таким образом, чтобы позволить разработчикам модулей сосредоточиться на своей специализации — написании кода и создании исходных дистрибутивов, — в то время как промежуточная категория, называемая *упаковщиками*, появляется, чтобы преобразовывать исходные дистрибутивы в собственные дистрибутивы для как можно большего числа платформ.

Конечно, разработчик модуля может быть своим собственным упаковщиком; или упаковщик может быть добровольцем «где-то там», у которого есть доступ к платформе, которой у первоначального разработчика нет; или это может быть программное обеспечение, периодически захватывающее новые исходные дистрибутивы и преобразующее их в собственные дистрибутивы для как можно большего числа платформ, к которым оно имеет доступ. Независимо от того, кто они такие, упаковщик использует скрипт setup и семейство команд bdist для создания собственных дистрибутивов.

В качестве простого примера, если я выполню следующую команду в дереве исходных кодов Distutils:

python setup.py bdist

то Distutils скомпилирует мой модульный дистрибутив (в данном случае сам Distutils), выполнит «фиктивную» установку (также в каталоге build) и создаст дистрибутив по умолчанию для моей платформы. По умолчанию собственные дистрибутивы на Unix – это «простой» архив tar, а на Windows – простой инсталлятор в виде исполняемого файла. (Этот архив tar считается «простым», потому что для его работы его нужно распаковать в определенном месте.)

Таким образом, выполнение вышеупомянутой команды на системе Unix создает Distutils-1.0.plat.tar.gz; извлечение этого архива tar из правильного места установит Distutils точно так же, как если бы вы скачали исходный дистрибутив и выполнили команду python setup.py install. («Правильное место» – это либо корень файловой системы, либо каталог Python prefix, в зависимости от параметров, заданных для команды bdist_dumb; по умолчанию создаваемые простые дистрибутивы относятся к каталогу prefix.)

Очевидно, что для чисто Python-дистрибутивов это не проще, чем просто выполнить команду python setup.py install, – но для дистрибутивов, не являющихся чисто Python (включающих расширения, которые необходимо скомпилировать), это может означать разницу между тем, смогут ли пользователи использовать ваши расширения или нет. А создание «интеллектуальных» собственных дистрибутивов, таких как пакет RPM или инсталлятор в виде исполняемого файла для Windows, гораздо удобнее для пользователей, даже если ваш дистрибутив не включает никаких расширений.

Команда bdist имеет опцию --formats, аналогичную команде sdist, которую можно использовать для выбора типов собственных дистрибутивов, которые нужно сгенерировать: например,

python setup.py bdist --format=zip

при выполнении на системе Unix создаст Distutils-1.0.plat.zip – опять же, этот архив нужно распаковать из корневого каталога для установки Distutils.

Доступные форматы для собственных дистрибутивов:

Формат

Описание

Примечания

gztar

Архив tar, сжатый gzip (.tar.gz)

(1)

bztar

Архив tar, сжатый bzip2 (.tar.bz2)

xztar

Архив tar, сжатый xz (.tar.xz)

ztar

Архив tar, сжатый другим архиватором (.tar.Z)

(3)

tar

Архив tar (.tar)

zip

Архив zip (.zip)

(2),(4)

rpm

RPM

(5)

pkgtool

Solaris pkgtool

sdux

HP-UX swinstall

msi

Инсталлятор Microsoft.

Изменено в версии 3.5: Добавлена поддержка формата xztar.

Примечания:

  1. по умолчанию в Unix
  2. по умолчанию в Windows
  3. требуется внешняя утилита compress.
  4. требуется либо внешняя утилита zip, либо модуль zipfile (входит в стандартную библиотеку Python с версии Python 1.6)
  5. требуется внешняя утилита rpm версии 3.0.4 или выше (используйте команду rpm --version для определения вашей версии)

Не обязательно использовать команду bdist с опцией --formats; вы также можете использовать команду, которая напрямую реализует интересующий вас формат. Некоторые из этих подкоманд bdist фактически генерируют несколько похожих форматов; например, команда bdist_dumb генерирует все «простые» форматы архивов (tar, gztar, bztar, xztar, ztar, и zip), а bdist_rpm генерирует как двоичные, так и исходные RPM-пакеты. Подкоманды bdist и генерируемые ими форматы:

Команда

Форматы

bdist_dumb

tar, gztar, bztar, xztar, ztar, zip

bdist_rpm

rpm, srpm

bdist_msi

msi

Примечание

bdist_msi устарела с версии Python 3.9.

В следующих разделах приведены подробные сведения об отдельных командах bdist_*.

5.1. Создание пакетов RPM

Формат RPM используется во многих популярных дистрибутивах Linux, включая Red Hat, SuSE и Mandrake. Если одна из этих (или любая другая основанная на RPM дистрибутив Linux) является вашей обычной средой, создание пакетов RPM для других пользователей этого же дистрибутива тривиально. В зависимости от сложности дистрибуции вашего модуля и различий между дистрибутивами Linux, вы также можете создать RPM-пакеты, которые будут работать на разных дистрибутивах, основанных на RPM.

Обычный способ создания RPM-пакета вашей дистрибуции модуля — выполнить команду bdist_rpm:

python setup.py bdist_rpm

или команду bdist с опцией --format:

python setup.py bdist --formats=rpm

Первая позволяет указать RPM-специфические опции; вторая позволяет легко указать несколько форматов в одном запуске. Если вам нужно сделать и то, и другое, вы можете явно указать несколько команд bdist_* и их опции:

python setup.py bdist_rpm --packager="John Doe <jdoe@example.org>"

Создание пакетов RPM управляется файлом .spec, так же как использование Distutils управляется скриптом setup. Для упрощения вашей работы, команда bdist_rpm обычно создаёт файл .spec на основе информации, которую вы предоставили в скрипте setup, в командной строке и во всех файлах конфигурации Distutils. Различные опции и разделы в файле .spec выводятся из опций в скрипте setup следующим образом:

Опция или раздел файла RPM .spec

Опция скрипта setup Distutils

Имя

name

Краткое описание (в преамбуле)

description

Версия

version

Производитель

author и author_email, или — & maintainer и maintainer_email

Авторские права

license

Url

url

%description (раздел)

long_description

Кроме того, в файлах .spec есть множество опций, у которых нет соответствующих опций в скрипте setup. Большинство из них обрабатываются через опции команды bdist_rpm следующим образом:

Опция или раздел файла RPM .spec

Опция bdist_rpm

Значение по умолчанию

Релиз

release

“1”

Группа

group

“Разработка/Библиотеки”

Производитель

vendor

(см. выше)

Упаковщик

packager

(нет)

Предоставляет

provides

(нет)

Требует

requires

(нет)

Конфликтует с

conflicts

(нет)

Устаревает

obsoletes

(нет)

Дистрибутив

distribution_name

(нет)

Требуется для сборки

build_requires

(нет)

Иконка

icon

(нет)

Очевидно, что предоставление даже нескольких из этих опций в командной строке было бы утомительным и подверженным ошибкам, поэтому лучше всего поместить их в файл конфигурации setup, setup.cfg — см. раздел Написание файла конфигурации Setup. Если вы распространяете или упаковываете много дистрибутивов Python-модулей, вы можете поместить опции, которые применяются ко всем из них, в свой личный файл конфигурации Distutils (~/.pydistutils.cfg). Если вы хотите временно отключить этот файл, вы можете передать опцию --no-user-cfg команде setup.py.

Существует три этапа создания двоичного RPM-пакета, все из которых автоматически обрабатываются Distutils:

  1. создание файла .spec, который описывает пакет (аналогично скрипту Distutils setup; фактически, большая часть информации из скрипта setup оказывается в файле .spec)
  2. создание исходного RPM
  3. создание «двоичного» RPM (который может или не может содержать двоичный код, в зависимости от того, содержит ли ваш дистрибутив модулей расширения Python)

Обычно RPM объединяет два последних шага; при использовании Distutils все три шага обычно объединяются.

Если хотите, вы можете разделить эти три шага. Вы можете использовать опцию --spec-only для создания командой bdist_rpm только файла .spec и завершения работы; в этом случае файл .spec будет записан в «каталог дистрибутива» — обычно dist/, но настраиваемый с помощью опции --dist-dir (обычно файл .spec оказывается глубоко в «дереве сборки», в временной папке, созданной командой bdist_rpm).

5.2. Кросс-компиляция в Windows

Начиная с Python 2.6, distutils способен к кросс-компиляции между платформами Windows. На практике это означает, что при установленных соответствующих инструментах вы можете использовать 32-битную версию Windows для создания 64-битных расширений и наоборот.

Для построения на альтернативной платформе укажите опцию --plat-name к команде сборки. Действительные значения в настоящее время «win32» и «win-amd64». Например, на 32-битной версии Windows вы можете выполнить:

python setup.py build --plat-name=win-amd64

чтобы создать 64-битную версию вашего расширения.

что создаст 64-битный установщик на вашей 32-битной версии Windows.

Для кросс-компиляции необходимо загрузить исходный код Python и перекомпилировать сам Python для целевой платформы — это невозможно из бинарной установки Python (поскольку .lib и т. д. файлы для других платформ не включены). На практике это означает, что пользователю 32-битной операционной системы потребуется использовать Visual Studio 2008, чтобы открыть решение PCbuild/PCbuild.sln в дереве исходного кода Python и создать конфигурацию «x64» проекта «pythoncore», прежде чем станет возможной кросс-компиляция расширений.

Обратите внимание, что по умолчанию Visual Studio 2008 не устанавливает 64-битные компиляторы или инструменты. Вам может потребоваться повторно выполнить процесс установки Visual Studio и выбрать эти инструменты (использование панели управления -> [Добавить/Удалить] программы является удобным способом проверки или изменения вашей существующей установки).

5.2.1. Скрипт после установки

Начиная с Python 2.3, можно указать скрипт после установки с помощью опции --install-script. Должно быть указано имя файла скрипта, и имя файла скрипта также должно быть включено в аргумент scripts функции setup.

Этот скрипт будет выполнен во время установки на целевой системе после копирования всех файлов, с argv[1] установленным в -install, и снова при удалении перед удалением файлов с argv[1] установленным в -remove.

Скрипт установки выполняется в рамках установщика Windows, каждый вывод (sys.stdout, sys.stderr) перенаправляется в буфер и будет отображаться в интерфейсе после завершения скрипта.

Некоторые функции, особенно полезные в этом контексте, доступны как дополнительные встроенные функции в скрипте установки.

directory_created(path)
file_created(path)

Эти функции следует вызывать, когда скрипт postinstall создаёт директорию или файл во время установки. Он зарегистрирует path в установщике, чтобы он удалялся при удалении дистрибутива. Для безопасности, директории удаляются только если они пустые.

get_special_folder_path(csidl_string)

Эта функция может использоваться для получения местоположений специальных папок в Windows, таких как «Пуск» или «Рабочий стол». Она возвращает полный путь к папке. csidl_string должно быть одной из следующих строк:

"CSIDL_APPDATA"

"CSIDL_COMMON_STARTMENU"
"CSIDL_STARTMENU"

"CSIDL_COMMON_DESKTOPDIRECTORY"
"CSIDL_DESKTOPDIRECTORY"

"CSIDL_COMMON_STARTUP"
"CSIDL_STARTUP"

"CSIDL_COMMON_PROGRAMS"
"CSIDL_PROGRAMS"

"CSIDL_FONTS"

Если папка не может быть получена, возникает OSError.

Доступные папки зависят от конкретной версии Windows и, вероятно, также от настроек. Подробную информацию см. в документации Microsoft по функции SHGetSpecialFolderPath().

create_shortcut(target, description, filename[, arguments[, workdir[, iconpath[, iconindex]]]])

Эта функция создаёт ярлык. target — путь к программе, которую будет запускать ярлык. description — описание ярлыка. filename — заголовок ярлыка, который будет виден пользователю. arguments — аргументы командной строки, если таковые имеются. workdir — рабочая директория для программы. iconpath — файл, содержащий иконку для ярлыка, а iconindex — индекс иконки в файле iconpath. Опять же, для получения подробной информации обратитесь к документации Microsoft для интерфейса IShellLink.

© 2001–2023 Python Software Foundation
Licensed under the PSF License.
https://docs.python.org/3.10/distutils/builtdist.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API