5. Создание встроенных дистрибутивов¶
Примечание
Этот документ будет храниться только до тех пор, пока в документации setuptools
по адресу https://setuptools.readthedocs.io/en/latest/setuptools.html самостоятельно не будет представлена вся соответствующая информация, которая в настоящее время включена в этот документ.
«Встроенный дистрибутив» - это то, о чем вы, вероятно, привыкли думать либо как о «бинарном пакете», либо как о «установщике» (в зависимости от вашего опыта). Однако это не обязательно двоичный файл, поскольку он может содержать только исходный код на Python и/или байт-код; и мы не называем его пакетом, потому что это слово уже используется в Python. (А «установщик» - это термин, специфичный для мира основных настольных систем).
Встроенный дистрибутив - это то, как вы максимально упрощаете жизнь установщикам вашего дистрибутива модулей: для пользователей Linux-систем на базе RPM это бинарный RPM-файл; для пользователей Windows - исполняемый установщик; для пользователей Linux на базе Debian - пакет Debian; и так далее. Очевидно, что ни один человек не сможет создать встроенные дистрибутивы для каждой платформы в мире, поэтому дистрибутивы предназначены для того, чтобы разработчики модулей могли сосредоточиться на своей специальности - написании кода и создании дистрибутивов с исходным кодом, в то время как появляется промежуточный вид под названием «упаковщики», который превращает дистрибутивы с исходным кодом в создавал дистрибутивы для стольких платформ, сколько существует упаковщиков.
Конечно, разработчик модуля может быть их собственным упаковщиком; или упаковщик может быть добровольцем «где-то там», у которого есть доступ к платформе, которой нет у оригинального разработчика; или это может быть программное обеспечение, периодически получающее новые исходные дистрибутивы и превращающее их во встроенные дистрибутивы для такого же количества платформ, как и программное обеспечение имеет доступ к. Независимо от того, кто это, упаковщик использует сценарий установки и семейство команд bdist для создания встроенных дистрибутивов.
В качестве простого примера, если я выполню следующую команду в дереве исходных текстов Distutils:
python setup.py bdist
затем Distutils создает дистрибутив моего модуля (в данном случае сам Distutils), выполняет «поддельную» установку (также в каталоге build
) и создает тип встроенного дистрибутива по умолчанию для моей платформы. Формат по умолчанию для встроенных дистрибутивов - это «тупой» tar-файл в Unix и простой исполняемый установщик в Windows. (Этот tar-файл считается «тупым», потому что для работы его необходимо распаковать в определенном месте).
Таким образом, приведенная выше команда в системе Unix создает Distutils-1.0.plat.tar.gz
; при распаковке этого хранилища из нужного места дистрибутивы устанавливаются точно так же, как если бы вы загрузили исходный код дистрибутива и запустили python setup.py install
. («Правильным местом» является либо корневой каталог файловой системы, либо каталог prefix
в Python, в зависимости от параметров, заданных команде 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
— опять же, этот архив будет распакован из корневого каталога для установки дистрибутивов.
Доступными форматами для встроенных дистрибутивов являются:
Формат |
Описание |
Записи |
---|---|---|
|
сжатый tar-файл ( |
(1) |
|
сжатый tar-файл ( |
|
|
сжатый tar-файл ( |
|
|
сжатый tar-файл ( |
(3) |
|
tar-файл ( |
|
|
zip-файл ( |
(2),(4) |
|
оборотов в минуту |
(5) |
|
Солярис 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, gz tar, bztar, xztar, ztar, почтовый индекс |
bdist_rpm |
обороты в минуту, об/мин |
В следующих разделах приведены подробные сведения об отдельных командах bdist_*.
5.1. Создание пакетов RPM¶
Формат RPM используется во многих популярных дистрибутивах Linux, включая Red Hat, SuSE и Mandrake. Если один из них (или любой другой дистрибутив Linux, основанный на RPM) является вашей обычной средой, создание пакетов 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
, так же как использование дистрибутивов управляется сценарием установки. Чтобы упростить вам жизнь, команда bdist_rpm обычно создает файл .spec
на основе информации, которую вы предоставляете в сценарии установки, в командной строке и в любых файлах конфигурации Distutils. Различные параметры и разделы в файле .spec
являются производными от параметров в сценарии установки следующим образом:
Частота вращения |
Параметр сценария установки дистрибутивов |
---|---|
Имя |
|
Краткое содержание (в преамбуле) |
|
Версия |
|
Продавец |
|
Авторское право |
|
URL-адрес |
|
%описание (раздел) |
|
Кроме того, в файлах .spec
есть множество опций, которым нет соответствующих опций в сценарии установки. Большинство из них обрабатываются с помощью опций команды bdist_rpm следующим образом:
Частота вращения |
bdist_rpm опция |
значение по умолчанию |
---|---|---|
Выпускать |
|
«1» |
Группа |
|
«Разработка/Библиотеки» |
Продавец |
|
(смотрите выше) |
Упаковщик |
|
(нет) |
Обеспечивает |
|
(нет) |
Требует |
|
(нет) |
Конфликты |
|
(нет) |
Устаревает |
|
(нет) |
Распределение |
|
(нет) |
Требования к строительству |
|
(нет) |
Икона |
|
(нет) |
Очевидно, что вводить даже некоторые из этих параметров в командной строке было бы утомительно и чревато ошибками, поэтому обычно лучше всего указывать их в файле конфигурации установки, setup.cfg
— см. раздел Запись установочного файла конфигурации. Если вы распространяете или упаковываете много дистрибутивов модулей Python, возможно, вам захочется поместить параметры, применимые ко всем из них, в свой личный конфигурационный файл Distutils (~/.pydistutils.cfg
). Если вы хотите временно отключить этот файл, вы можете изменить параметр --no-user-cfg
на setup.py
.
Создание двоичного пакета RPM состоит из трех шагов, каждый из которых автоматически обрабатывается дистрибутивами:
создайте файл
.spec
, который описывает пакет (аналогично сценарию установки Distutils; на самом деле, большая часть информации в сценарии установки содержится в файле.spec
).создайте исходный RPM
создайте «двоичный» RPM (который может содержать или не содержать двоичный код, в зависимости от того, содержит ли ваш дистрибутив модуля расширения Python).
Обычно RPM объединяет последние два шага; когда вы используете дистрибутивы, все три шага обычно объединяются вместе.
Если хотите, вы можете разделить эти три шага. Вы можете использовать опцию --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 для функции установки.
Этот скрипт будет запущен во время установки в целевой системе после того, как все файлы будут скопированы, с параметром argv[1]
, равным -install
, и снова во время деинсталляции перед удалением файлов с параметром argv[1]
, равным -remove
.
Скрипт установки запускается встроенным в установщик Windows, каждый вывод (sys.stdout
, sys.stderr
) перенаправляется в буфер и будет отображаться в графическом интерфейсе пользователя после завершения работы скрипта.
Некоторые функции, особенно полезные в этом контексте, доступны в качестве дополнительных встроенных функций в сценарии установки.
- directory_created(path)¶
- file_created(path)¶
Эти функции должны вызываться при создании каталога или файла скриптом postinstall во время установки. Он зарегистрирует путь в программе удаления, чтобы он был удален при удалении дистрибутива. На всякий случай каталоги удаляются только в том случае, если они пусты.
- 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
.