5. Створення вбудованих дистрибутивів¶
Примітка
Цей документ зберігається лише до тих пір, поки документація setuptools
за адресою https://setuptools.readthedocs.io/en/latest/setuptools.html окремо не охопить всю відповідну інформацію, яка зараз включена тут.
«Вбудований дистрибутив» — це те, що ви, ймовірно, звикли вважати «двійковим пакетом» або «інсталятором» (залежно від вашого досвіду). Однак він не обов’язково є двійковим, оскільки він може містити лише вихідний код Python та/або байт-код; і ми не називаємо це пакетом, тому що це слово вже вимовлено в Python. (А «інсталятор» — це термін, характерний для світу основних настільних систем.)
Вбудований дистрибутив – це те, як ви максимально полегшуєте життя інсталяторам вашого дистрибутива модуля: для користувачів систем Linux на основі RPM це двійковий RPM; для користувачів Windows це виконуваний інсталятор; для користувачів Linux на базі Debian це пакет Debian; і так далі. Очевидно, що ніхто не зможе створити вбудовані дистрибутиви для будь-якої платформи під сонцем, тому Distutils розроблено, щоб дозволити розробникам модулів зосередитися на своїй спеціальності — написанні коду та створенні вихідних дистрибутивів — тоді як проміжний вид, який називається packagers з’являється, щоб перетворити вихідні дистрибутиви на вбудовані дистрибутиви для стільки платформ, скільки пакувальників.
Звичайно, розробник модуля може бути власним пакувальником; або пакувальник може бути волонтером «десь там», який має доступ до платформи, якого не має оригінальний розробник; або це може бути програмне забезпечення, яке періодично збирає нові вихідні дистрибутиви та перетворює їх на вбудовані дистрибутиви для стількох платформ, до яких програмне забезпечення має доступ. Незалежно від того, ким вони є, пакетувальник використовує сценарій налаштування та сімейство команд bdist для створення вбудованих дистрибутивів.
Як простий приклад, якщо я запусту таку команду в дереві вихідних кодів Distutils:
python setup.py bdist
потім Distutils збирає мій дистрибутив модуля (у цьому випадку сам Distutils), виконує «підроблену» інсталяцію (також у каталозі build
) і створює стандартний тип вбудованого дистрибутива для моєї платформи. Типовим форматом для вбудованих дистрибутивів є «тупий» файл tar в Unix і простий виконуваний інсталятор у Windows. (Цей файл tar вважається «тупим», оскільки для роботи його потрібно розпакувати в певному місці.)
Таким чином, наведена вище команда в системі Unix створює Distutils-1.0.plat.tar.gz
; розпакування цього архіву з потрібного місця встановлює 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.
Доступні формати для вбудованих дистрибутивів:
Формат |
Опис |
Примітки |
---|---|---|
|
gzipped tar файл ( |
(1) |
|
bzip-файл tar ( |
|
|
xzipped файл tar ( |
|
|
стиснутий файл tar ( |
(3) |
|
tar-файл ( |
|
|
zip-файл ( |
(2), (4) |
|
RPM |
(5) |
|
Solaris pkgtool |
|
|
HP-UX swinstall |
|
|
self-extracting ZIP file for 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 is deprecated since Python 3.8.
Примітка
bdist_msi is deprecated since Python 3.9.
У наступних розділах наведено детальну інформацію про окремі команди 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>" \
bdist_wininst --target-version="2.0"
Створення пакетів RPM керується файлом .spec
, подібно до того, як використання Distutils керується сценарієм встановлення. Щоб полегшити ваше життя, команда bdist_rpm зазвичай створює файл .spec
на основі інформації, яку ви надаєте в сценарії встановлення, у командному рядку та в будь-яких конфігураційних файлах Distutils. Різні параметри та розділи у файлі .spec
походять від параметрів у сценарії налаштування таким чином:
Параметр або розділ файлу RPM |
Параметр сценарію налаштування Distutils |
---|---|
Ім’я |
|
Резюме (у преамбулі) |
|
Версія |
|
Продавець |
|
Авторське право |
|
Url |
|
%dопис (розділ) |
|
Крім того, у файлах .spec
є багато параметрів, які не мають відповідних параметрів у сценарії встановлення. Більшість із них обробляються за допомогою параметрів команди bdist_rpm наступним чином:
Параметр або розділ файлу RPM |
параметр bdist_rpm |
значення за замовчуванням |
---|---|---|
Реліз |
|
«1» |
Група |
|
«Розвиток/Бібліотеки» |
Продавець |
|
(Дивись вище) |
пакувальник |
|
(жоден) |
Забезпечує |
|
(жоден) |
Вимагає |
|
(жоден) |
Конфлікти |
|
(жоден) |
Застарілі |
|
(жоден) |
Розподіл |
|
(жоден) |
BuildRequires |
|
(жоден) |
значок |
|
(жоден) |
Очевидно, що надання навіть кількох із цих параметрів у командному рядку було б виснажливим і спричинило помилки, тому зазвичай краще розмістити їх у файлі конфігурації установки, setup.cfg
— дивіться розділ Написання файлу конфігурації установки. Якщо ви розповсюджуєте або пакуєте багато дистрибутивів модулів Python, ви можете розмістити параметри, які стосуються всіх них, у вашому особистому файлі конфігурації Distutils (~/.pydistutils.cfg
). Якщо ви хочете тимчасово вимкнути цей файл, ви можете передати параметр --no-user-cfg
до setup.py
.
Створення бінарного пакета RPM складається з трьох кроків, усі з яких автоматично обробляються Distutils:
створіть файл
.spec
, який описує пакунок (аналогічно сценарію налаштування Distutils; насправді велика частина інформації в сценарії налаштування зберігається у файлі.spec
)створити вихідний RPM
створити «бінарний» RPM (який може містити або не містити двійковий код, залежно від того, чи містить ваш дистрибутив модуля розширення Python)
Зазвичай RPM об’єднує останні два кроки разом; коли ви використовуєте Distutils, усі три кроки зазвичай об’єднуються разом.
Якщо ви бажаєте, ви можете розділити ці три кроки. Ви можете використати параметр --spec-only
, щоб bdist_rpm просто створив файл .spec
і вийшов; у цьому випадку файл .spec
буде записаний у «каталог розповсюдження» — зазвичай dist/
, але його можна налаштувати за допомогою параметра --dist-dir
. (Зазвичай файл .spec
знаходиться глибоко в «дереві побудови», у тимчасовому каталозі, створеному bdist_rpm.)
5.2. Creating Windows Installers¶
Попередження
bdist_wininst is deprecated since Python 3.8.
Попередження
bdist_msi is deprecated since Python 3.9.
Executable installers are the natural format for binary distributions on Windows. They display a nice graphical user interface, display some information about the module distribution to be installed taken from the metadata in the setup script, let the user select a few options, and start or cancel the installation.
Since the metadata is taken from the setup script, creating Windows installers is usually as easy as running:
python setup.py bdist_wininst
or the bdist command with the --formats
option:
python setup.py bdist --formats=wininst
If you have a pure module distribution (only containing pure Python modules and
packages), the resulting installer will be version independent and have a name
like foo-1.0.win32.exe
. Note that creating wininst
binary
distributions in only supported on Windows systems.
If you have a non-pure distribution, the extensions can only be created on a
Windows platform, and will be Python version dependent. The installer filename
will reflect this and now has the form foo-1.0.win32-py2.0.exe
. You
have to create a separate installer for every Python version you want to
support.
The installer will try to compile pure modules into bytecode after installation
on the target system in normal and optimizing mode. If you don’t want this to
happen for some reason, you can run the bdist_wininst command with
the --no-target-compile
and/or the --no-target-optimize
option.
By default the installer will display the cool «Python Powered» logo when it is
run, but you can also supply your own 152x261 bitmap which must be a Windows
.bmp
file with the --bitmap
option.
The installer will also display a large title on the desktop background window
when it is run, which is constructed from the name of your distribution and the
version number. This can be changed to another text by using the
--title
option.
The installer file will be written to the «distribution directory» — normally
dist/
, but customizable with the --dist-dir
option.
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
to build a 64bit version of your extension. The Windows Installers also support this option, so the command:
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 функції налаштування.
Цей сценарій буде запущено під час інсталяції в цільовій системі після того, як усі файли буде скопійовано, з параметром argv[1]
встановленим на -install
, і знову під час деінсталяції перед видаленням файлів зі значенням argv[1]
-remove
.
Сценарій інсталяції працює вбудовано в інсталятор Windows, кожен вихід (sys.stdout
, sys.stderr
) перенаправляється в буфер і відображатиметься в графічному інтерфейсі після завершення сценарію.
Деякі функції, особливо корисні в цьому контексті, доступні як додаткові вбудовані функції в сценарії встановлення.
-
directory_created
(path)¶ -
file_created
(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]]]])¶ Ця функція створює ярлик. ціль — це шлях до програми, яка запускається за допомогою ярлика. description — це опис ярлика. ім’я файлу – це назва ярлика, який побачить користувач. arguments визначає аргументи командного рядка, якщо такі є. workdir — це робочий каталог для програми. iconpath — це файл, що містить піктограму для ярлика, а iconindex — це індекс піктограми у файлі iconpath. Знову ж таки, для отримання детальної інформації зверніться до документації Microsoft для інтерфейсу
IShellLink
.
5.4. Vista User Access Control (UAC)¶
Starting with Python 2.6, bdist_wininst supports a --user-access-control
option. The default is „none“ (meaning no UAC handling is done), and other
valid values are „auto“ (meaning prompt for UAC elevation if Python was
installed for all users) and „force“ (meaning always prompt for elevation).
Примітка
bdist_wininst is deprecated since Python 3.8.
Примітка
bdist_msi is deprecated since Python 3.9.