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— опять же, этот архив будет распакован из корневого каталога для установки дистрибутивов.

Доступными форматами для встроенных дистрибутивов являются:

Формат

Описание

Записи

gztar

сжатый tar-файл (.tar.gz)

(1)

bztar

сжатый tar-файл (.tar.bz2)

xztar

сжатый tar-файл (.tar.xz)

ztar

сжатый tar-файл (.tar.Z)

(3)

tar

tar-файл (.tar)

zip

zip-файл (.zip)

(2),(4)

rpm

оборотов в минуту

(5)

pkgtool

Солярис pkgtool

sdux

HP-UX swinstall

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, 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 являются производными от параметров в сценарии установки следующим образом:

Частота вращения .spec параметр файла или раздела

Параметр сценария установки дистрибутивов

Имя

name

Краткое содержание (в преамбуле)

description

Версия

version

Продавец

author и author_email, или — & maintainer и maintainer_email

Авторское право

license

URL-адрес

url

%описание (раздел)

long_description

Кроме того, в файлах .spec есть множество опций, которым нет соответствующих опций в сценарии установки. Большинство из них обрабатываются с помощью опций команды bdist_rpm следующим образом:

Частота вращения .spec параметр файла или раздела

bdist_rpm опция

значение по умолчанию

Выпускать

release

«1»

Группа

group

«Разработка/Библиотеки»

Продавец

vendor

(смотрите выше)

Упаковщик

packager

(нет)

Обеспечивает

provides

(нет)

Требует

requires

(нет)

Конфликты

conflicts

(нет)

Устаревает

obsoletes

(нет)

Распределение

distribution_name

(нет)

Требования к строительству

build_requires

(нет)

Икона

icon

(нет)

Очевидно, что вводить даже некоторые из этих параметров в командной строке было бы утомительно и чревато ошибками, поэтому обычно лучше всего указывать их в файле конфигурации установки, setup.cfg— см. раздел Запись установочного файла конфигурации. Если вы распространяете или упаковываете много дистрибутивов модулей Python, возможно, вам захочется поместить параметры, применимые ко всем из них, в свой личный конфигурационный файл Distutils (~/.pydistutils.cfg). Если вы хотите временно отключить этот файл, вы можете изменить параметр --no-user-cfg на setup.py.

Создание двоичного пакета RPM состоит из трех шагов, каждый из которых автоматически обрабатывается дистрибутивами:

  1. создайте файл .spec, который описывает пакет (аналогично сценарию установки Distutils; на самом деле, большая часть информации в сценарии установки содержится в файле .spec).

  2. создайте исходный RPM

  3. создайте «двоичный» 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.

Вернуться на верх