Создание собранных дистрибутивов
Примечание
Этот документ сохраняется только до тех пор, пока документация 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.
Доступные форматы собранных дистрибутивов:
Формат | Описание | Примечания |
|---|---|---|
| Архив tar с gzip-сжатием ( | (1) |
| Архив tar с bzip2-сжатием ( | |
| Архив tar со xz-сжатием ( | |
| Архив tar со сжатием ( | (3) |
| Архив tar ( | |
| Архив zip ( | (2),(4) |
| RPM | (5) |
| Solaris pkgtool | |
| HP-UX swinstall | |
| самораспаковывающийся архив ZIP для Windows | (4) |
| Установка Microsoft. |
Изменено в версии 3.5: Добавлена поддержка формата xztar.
Примечания:
- по умолчанию в Unix
- по умолчанию в Windows
- требуется внешняя утилита compress.
- требуется либо внешняя утилита zip, либо модуль
zipfile(входит в стандартную библиотеку Python с Python 1.6) - требуется внешняя утилита 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_MARKER5.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 | Опция скрипта setup Distutils |
|---|---|
Имя |
|
Краткое описание (в преамбуле) |
|
Версия |
|
Производитель |
|
Авторские права |
|
URL |
|
%description (раздел) |
|
Кроме того, существует множество опций в файлах .spec, которые не имеют соответствующих опций в скрипте setup. Большинство из них обрабатываются с помощью опций команды bdist_rpm следующим образом:
Опция или раздел файла RPM | Опция bdist_rpm | Значение по умолчанию |
|---|---|---|
Релиз |
| “1” |
Группа |
| “Разработка/Библиотеки” |
Производитель |
| (см. выше) |
Упаковщик |
| (нет) |
Предоставляет |
| (нет) |
Требует |
| (нет) |
Конфликтует |
| (нет) |
Заменяет |
| (нет) |
Дистрибутив |
| (нет) |
Требуется для сборки |
| (нет) |
Иконка |
| (нет) |
Очевидно, предоставление даже нескольких из этих опций в командной строке было бы утомительным и подверженным ошибкам, поэтому обычно лучше всего поместить их в файл конфигурации setup, setup.cfg—см. раздел Написание файла конфигурации Setup. Если вы распространяете или упаковываете много дистрибутивов модулей Python, вы можете поместить опции, которые применяются ко всем из них, в свой личный файл конфигурации Distutils (~/.pydistutils.cfg). Если вы хотите временно отключить этот файл, вы можете передать опцию --no-user-cfg команде setup.py.
Создание двоичного RPM-пакета состоит из трёх шагов, все из которых автоматически обрабатываются Distutils:
- создание файла
.spec, который описывает пакет (аналогично скрипту setup Distutils; на самом деле большая часть информации из скрипта setup попадает в файл.spec) - создание исходного RPM-пакета
- создание «двоичного» 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