Spec-Zone.ru › Python 3.9

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

Примечание

Этот документ сохраняется только до тех пор, пока документация 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) и создаст дистрибутив по умолчанию для моей платформы. Формат дистрибутива по умолчанию — это «простой» архив tar на Unix и простой установочный файл на 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, — но для нечистовых дистрибутивов, включающих расширения, которые необходимо скомпилировать, это может означать разницу между тем, сможет ли кто-то использовать ваши расширения или нет. А создание «умных» собственных дистрибутивов, таких как пакет 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

wininst

самораспаковывающийся архив ZIP для Windows

(4)

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_wininst

wininst

bdist_msi

msi

Примечание

bdist_wininst устарела с Python 3.8.

Примечание

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>" \
                bdist_wininst --target-version="2.0"

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

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

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

5.2. Создание установщиков для Windows

Предупреждение

bdist_wininst устарел с Python 3.8.

Предупреждение

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

Исполняемые установщики являются естественным форматом для двоичных дистрибутивов в Windows. Они отображают удобный графический пользовательский интерфейс, отображают некоторую информацию о модульном дистрибутиве, который будет установлен, взятую из метаданных в скрипте setup, позволяют пользователю выбрать несколько параметров и начать или отменить установку.

Поскольку метаданные берутся из скрипта setup, создание установщиков для Windows обычно так же просто, как запуск:

python setup.py bdist_wininst

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

python setup.py bdist --formats=wininst

Если у вас чистый модульный дистрибутив (только чистые модули и пакеты Python), полученный установщик будет независимым от версии и иметь имя, подобное foo-1.0.win32.exe. Обратите внимание, что создание двоичных дистрибутивов wininst поддерживается только в системах Windows.

Если у вас есть дистрибутив, не являющийся чистым, расширения можно создать только в среде Windows, и они будут зависеть от версии Python. Имя файла установщика будет отражать это, и теперь имеет вид foo-1.0.win32-py2.0.exe. Вам нужно создать отдельный установщик для каждой поддерживаемой версии Python.

Установкащик попытается скомпилировать чистые модули в байткод после установки на целевую систему в обычном и оптимизирующем режиме. Если вы по какой-либо причине не хотите, чтобы это происходило, вы можете запустить команду bdist_wininst с опцией --no-target-compile и/или опцией --no-target-optimize.

По умолчанию установщик будет отображать логотип «Python Powered», но вы также можете предоставить собственный 152x261 битовый рисунок, который должен быть файлом Windows .bmp с опцией --bitmap.

Установкащик также отобразит большой заголовок на экране рабочего стола при запуске, построенный из имени вашего дистрибутива и номера версии. Это можно изменить на другой текст, используя опцию --title.

Файл установщика будет записан в «каталог дистрибуции» — обычно dist/, но настраиваемый с помощью опции --dist-dir.

5.3. Компиляция для разных платформ в 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-битную версию вашего расширения. Установщики Windows также поддерживают эту опцию, поэтому команда:

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

создаст исполняемый файл установки 64-битной версии на вашей 32-битной версии Windows.

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

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

5.3.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.

5.4. Контроль доступа пользователя в Vista (UAC)

Начиная с Python 2.6, bdist_wininst поддерживает опцию --user-access-control. По умолчанию она равна ‘none’ (т. е. обработка UAC не выполняется), а другие допустимые значения — ‘auto’ (что означает запрос на повышение привилегий UAC, если Python был установлен для всех пользователей) и ‘force’ (что означает всегда запрос на повышение привилегий).

Примечание

bdist_wininst устарел начиная с Python 3.8.

Примечание

bdist_msi устарел начиная с Python 3.9.

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

Spec-Zone.ru

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