Создание собственных дистрибутивов
Примечание
Данный документ сохраняется только до тех пор, пока документация 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 | |
| Установщик 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_*.
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 | Опция скрипта 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, который описывает пакет (аналогично скрипту Distutils setup; на самом деле большая часть информации в скрипте setup попадает в файл.spec) - создание исходного RPM
- создание «бинарного» 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.11/distutils/builtdist.html