Spec-Zone.ru › Python 3.8

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

Примечание

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

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

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

Конечно, разработчик модуля может быть и своим упаковщиком; или упаковщик может быть добровольцем «где-то там», у которого есть доступ к платформе, которой нет у первоначального разработчика; или это может быть программное обеспечение, периодически собирающее новые исходные дистрибутивы и преобразующее их в собранные дистрибутивы для как можно большего количества платформ, к которым у программного обеспечения есть доступ. Независимо от того, кто они, упаковщик использует скрипт установки и семейство команд 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_*.

END_OF_DOCUMENT_MARKER

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.

Исполняемые установщики — это естественный формат двоичных дистрибутивов в 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 и, вероятно, также от конфигурации. Для получения подробной информации обратитесь к документации Майкрософт для функции SHGetSpecialFolderPath().

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

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

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

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

Примечание

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

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

Spec-Zone.ru

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