5. Tworzenie Zbudowanych Dystrybucji

Informacja

Ten dokument jest przechowywany wyłącznie do czasu, gdy dokumentacja setuptools pod adresem https://setuptools.readthedocs.io/en/latest/setuptools.html niezależnie obejmie wszystkie istotne informacje, które są tutaj zawarte.

„Zbudowana dystrybucja” jest pewnie tym do czego przyzwyczaiłeś się myśleć gdy napotykasz „binarny pakiet” lub „instalator” (w zależności od twoich dotychczasowych doświadczeń). Nie jest ona jednak koniecznie binarna, gdyż może zawierać tylko kod w języku pytonowskim i/lub kod-kęsowy; i nie nazywamy jej pakietem, gdyż ten termin jest już zarezerwowany w języku pytonowskim. (Zaś „instalator” jest terminem szczególnym dla świata systemów typu desktop głównego nurtu.)

Zbudowana dystrybucja to sposób w jaki możesz ułatwić życie tak bardzo jak to jest możliwe dla osób instalujących dystrybucję twojego modułu: dla użytkowników systemu Linux opartego o pakiety RPM, jest to binarny RPM; dla użytkowników Windows, jest to wykonywalny instalator; dla użytkowników systemu Linux opartego o Debiana jest to pakiet Debiana, itd. Oczywiście nikt przy zdrowych zmysłach nie jest w stanie tworzyć zbudowanych dystrybucji dla każdej maszyny/środowiska pod słońcem, więc Distutils są pomyślane tak aby umożliwić twórcom modułów skupienie się na tym na czym się znają najlepiej—pisaniu kodu i tworzeniu dystrybucji źródłowej—podczas gdy kasta pośrednicząca zwana pakieciarzami narodziła się aby zamieniać dystrybucje źródłowe w zbudowane dystrybucje dla tak wielu maszyn/środowisk jak wielu jest pakieciarzy.

Of course, the module developer could be their own packager; or the packager could be a volunteer „out there” somewhere who has access to a platform which the original developer does not; or it could be software periodically grabbing new source distributions and turning them into built distributions for as many platforms as the software has access to. Regardless of who they are, a packager uses the setup script and the bdist command family to generate built distributions.

Jako prosty przykład, jeśli uruchomię następujące polecenie na drzewie źródeł Distutils:

python setup.py bdist

wtedy Distutils buduje dystrybucję mojego modułu (samo Distutils w tym przypadku), wykonuje „fałszywą” instalację (także w katalogu build), i tworzy domyślny rodzaj zbudowanej dystrybucji dla mojej maszyny/środowiska. Domyślnym formatem dla zbudowanych dystrybucji jest „durny” plik tar na Unix-ie, i prosty wykonywalny instalator w Windows. (Ten plik tar jest uznawany za „głupi” gdyż musi zostać rozpakowany w szczególnym miejscu aby mógł zadziałać.)

Więc, powyższe polecenie tworzy w systemie Unix plik Distutils`1.0.plat.tar.gz; rozpakowanie tego tarball-a z właściwego miejsca instaluje Distutils tak, jakbyś ściągnął dystrybucję źródłową i uruchomił python setup.py install („właściwe miejsce” to zarówno katalog nadrzędny systemu plików lub katalog prefix języka pytonowskiego, zależnie od opcji przekazanych poleceniu bdist_dumb; domyślnie jest to robienie niezbyt-mądrej dystrybucji w odniesieniu do prefix.)

Oczywiście, dla czystych dystrybucji języka pytonowskiego, to nie jest w żaden sposób prostsze niż po prostu uruchomienie python setup.py install—ale dla dystrybucji „nie”-czystych, które zawierają rozszerzenia które wymagają kompilacji, może to mieć znaczenie dla kogoś kto będzie mógł użyć twoich rozszerzeń lub nie. Zaś tworzenie „inteligentnie” zbudowanych dystrybucji, takich jak pakiet RPM lub instalator wykonywalny dla Windows, jest dużo prostsze dla użytkowników nawet jeśli twoja dystrybucja nie zawiera żadnych rozszerzeń.

The bdist command has a --formats option, similar to the sdist command, which you can use to select the types of built distribution to generate: for example,

python setup.py bdist --format=zip

mogłoby gdy uruchomione na systemie Unix-owym, stworzyć plik Distutils-1.0.plat.zip—znów, to archiwum mogłoby być rozpakowane z katalogu nadrzędnego systemu plików w celu zainstalowania Distutils.

Dostępne formaty dla zbudowanych dystrybucji to:

Format

Opis

Notatki

gztar

gzip-nięty plik tar (.tar.gz)

(1)

bztar

bzipped tar file (.tar.bz2)

xztar

xzipped tar file (.tar.xz)

ztar

skompresowany plik tar (file`.tar.Z`)

(3)

tar

plik tar (.tar)

zip

plik zip (.zip)

(2),(4)

rpm

RPM

(5)

pkgtool

Solarisowe narzędzie pkgtool

sdux

program systemu HP-UX swinstall

wininst

samo-rozpakowujące się archiwum ZIP dla Windows

(4)

msi

Instalator Microsoft

Zmienione w wersji 3.5: Added support for the xztar format.

Uwagi:

  1. domyślne dla Unix

  2. domyślne dla Windows

  3. requires external compress utility.

  4. wymaga zewnętrznego programu użytkowego zip lub modułu zipfile (części standardowej biblioteki języka pytonowskiego od wersji 1.6 języka pytonowskiego)

  5. wymaga zewnętrznego programu użytkowego rpm, w wersji 3.0.4 lub lepszej (użyj rpm --version aby dowiedzieć się, którą wersję posiadasz)

You don’t have to use the bdist command with the --formats option; you can also use the command that directly implements the format you’re interested in. Some of these bdist „sub-commands” actually generate several similar formats; for instance, the bdist_dumb command generates all the „dumb” archive formats (tar, gztar, bztar, xztar, ztar, and zip), and bdist_rpm generates both binary and source RPMs. The bdist sub-commands, and the formats generated by each, are:

Polecenie

Formaty

bdist_dumb

tar, gztar, bztar, xztar, ztar, zip

bdist_rpm

rpm, srpm

bdist_wininst

wininst

bdist_msi

msi

Informacja

bdist_wininst is deprecated since Python 3.8.

Następujące paragrafy opowiadają w szczegółach o poszczególnych poleceniach bdist_*

5.1. Tworzenie pakietów RPM

Format RPM jest używany przez wiele popularnych dystrybucji Linuxa, włączając w to Red Hat, SuSE, i Mandrake. Jeśli jeden z nich (lub jakiekolwiek inne oparte o RPM dystrybucje Linuxa) są twoim typowym środowiskiem, tworzenie pakietów RPM dla innych użytkowników tej samej dystrybucji jest trywialne. W zależności od złożoności dystrybucji twojego modułu i różnic pomiędzy dystrybucjami Linux-a możesz być w stanie stworzyć RPMy, które współpracują z różnymi opartymi-o-RPM dystrybucjami.

Zwykłym sposobem na utworzenie RPMu twojej dystrybucji modułu jest uruchomienie polecenia bdist_rpm:

python setup.py bdist_rpm

or the bdist command with the --format option:

python setup.py bdist --formats=rpm

To pierwsze pozwala ci określić szczególne-dla-RPM opcje; to ostatnie pozwala Ci łatwo tworzyć wiele formatów za jednym zamachem. Jeśli potrzebujesz zrobić obydwu, możesz jawnie wyszczególnić wiele poleceń bdist_* i ich opcji:

python setup.py bdist_rpm --packager="John Doe <jdoe@example.org>" \
                bdist_wininst --target-version="2.0"

Tworzenie pakietu RPM jest napędzane plikiem .spec, tak jak używanie Distutils jest napędzane skryptem instalacyjnym. Aby ułatwić ci życie, polecenie bidst_rpm zwykle tworzy plik .spec oparte o informację którą mu dostarczasz w skrypcie instalacyjnym, w wierszu poleceń, i w plikach konfiguracyjnych Distutils. Różne opcje i sekcje w pliku .spec są pochodnymi po opcjach w skrypcie instalacyjnym w następujący sposób:

plik RPM .spec opcja lub sekcja

opcja skryptu instalacyjnego Distutils

Nazwa

nazwa

Podsumowanie (w preambule)

opis

Wersja

wersja

Dostawca

author and author_email, or — & maintainer and maintainer_email

Prawa autorskie

licencja

adres Url

url

%opis (sekcja)

dlugi_opis

Dodatkowo, istnieje wiele opcji w plikach .spec które nie muszą mieć odpowiadających opcji w skrypcie instalacyjnym. Większość z tych jest obsługiwana przez opcje polecenia bdist_rpm jak następuje:

plik RPM .spec opcja lub sekcja

bdist_rpm option

wartość domyślna

Wydanie

release

„1”

Grupa

group

„Rozwój/Biblioteki”

Dostawca

vendor

(zobacz powyżej)

Pakujący

packager

(żaden)

Dostarcza

provides

(żaden)

Wymaga

requires

(żaden)

Konflikty

conflicts

(żaden)

Zbędne

obsoletes

(żaden)

Dystrybucja

distribution_name

(żaden)

ZbudowanieWymaga

build_requires

(żaden)

Obrazek

icon

(żaden)

Obviously, supplying even a few of these options on the command-line would be tedious and error-prone, so it’s usually best to put them in the setup configuration file, setup.cfg—see section Pisanie pliku konfiguracyjnego instalacji. If you distribute or package many Python module distributions, you might want to put options that apply to all of them in your personal Distutils configuration file (~/.pydistutils.cfg). If you want to temporarily disable this file, you can pass the --no-user-cfg option to setup.py.

Istnieją trzy kroki do zbudowania binarnego pakietu RPM, z których wszystkie są obsługiwane automatycznie przez Distutils:

  1. utwórz plik .spec, który opisuje pakiet (analogiczny do skryptu instalacyjnego Distutils; w rzeczywistości, większość informacji w skrypcie instalacyjnym ląduje do pliku .spec)

  2. stwórz źródłowy RPM

  3. stwórz „binarny” pakiet RPM (który może zawierać lub może nie zawierać kodu binarnego, w zależności od tego czy dystrybucja modułu zawiera rozszerzenia języka pytonowskiego)

Zwykle, pakiet RPM gromadzi dwa ostatnie kroki razem; gdy używasz Distutils, wszystkie trzy kroki są zwyczajowo zgromadzone razem.

If you wish, you can separate these three steps. You can use the --spec-only option to make bdist_rpm just create the .spec file and exit; in this case, the .spec file will be written to the „distribution directory”—normally dist/, but customizable with the --dist-dir option. (Normally, the .spec file winds up deep in the „build tree,” in a temporary directory created by bdist_rpm.)

5.2. Tworzenie Instalatorów Windows

Ostrzeżenie

bdist_wininst is deprecated since Python 3.8.

Wykonywalne instalatory są zwykłym formatem dla binarnych dystrybucji w Windows. Wyświetlają miły graficzny sprzęg użytkownika, wyświetlają pewne informacje o dystrybucji modułu do zainstalowania wziętej z opisu pakietu ze skryptu instalacyjnego, pozwalają użytkownikowi wybrać kilka opcji, i zacząć lub anulować instalację.

Ponieważ meta-dane wzięte są ze skryptu instalacyjnego, tworzenie instalatorów Windows jest zwykle tak proste jak uruchomienie:

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.

Jeśli masz „nie”czystą dystrybucję, rozszerzenia mogą być tylko tworzone na maszynie/środowisku Windowsowym, i będą zależne od wersji języka pytonowskiego. Nazwa pliku instalatora będzie odzwierciedlać to i będzie miała postać foo-1.0.win32-py2.0.exe. Musisz utworzyć oddzielny instalator dla każdej wersji języka pytonowskiego, którą zamierzasz wspierać.

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. Krzyżowa-kompilacja w Windows.

Poczynając od języka pytonowskiego 2.6, distutils jest w stanie krzyżowo-kompilować pomiędzy maszynami/środowiskami windowsowskimi. W praktyce, to oznacza, że z właściwymi narzędziami zainstalowanymi, możesz użyć 32bitowej wersji Windows aby utworzyć 64bitowe rozszerzenia i odwrotnie (64 bitowego Windowsa aby utworzyć 32 bitowe rozszerzenia).

To build for an alternate platform, specify the --plat-name option to the build command. Valid values are currently «win32», and «win-amd64». For example, on a 32bit version of Windows, you could execute:

python setup.py build --plat-name=win-amd64

aby zbudować 64bitową wersję rozszerzenia. Instalatory Windows także wspierają tą opcję, więc polecenie:

python setup.py build --plat-name=win-amd64 bdist_wininst

stworzyłoby 64-bitowy plik wykonywalny instalacji na twojej 32-bitowej wersji Windows.

To cross-compile, you must download the Python source code and cross-compile Python itself for the platform you are targeting - it is not possible from a binary installation of Python (as the .lib etc file for other platforms are not included.) In practice, this means the user of a 32 bit operating system will need to use Visual Studio 2008 to open the PCbuild/PCbuild.sln solution in the Python source tree and build the „x64” configuration of the «pythoncore» project before cross-compiling extensions is possible.

Zauważ że domyślnie, Visual Studio 2008 nie instaluje kompilatorów 64-bitowych kompilatorów ani narzędzi. Możesz potrzebować przejść jeszcze raz proces instalacyjny Visual Studio i wybrać te narzędzia (używanie Panelu Sterowania->[Dodaj/Usuń] Programy jest wygodnym sposobem aby sprawdzić lub zmodyfikować istniejącą instalację.)

5.3.1. Skrypt poinstalacyjny

Starting with Python 2.3, a postinstallation script can be specified with the --install-script option. The basename of the script must be specified, and the script filename must also be listed in the scripts argument to the setup function.

This script will be run at installation time on the target system after all the files have been copied, with argv[1] set to -install, and again at uninstallation time before the files are removed with argv[1] set to -remove.

Skrypt instalacyjny uruchamia się załączony w instalatorze windows, każde wyjście (sys.stdout, sys.stderr) jest przekierowane do bufora i zostanie wyświetlona w GUI (sprzęgu graficznym użytkownika) po tym jak skrypt się zakończy.

Niektóre zadania szczególnie użyteczne w tym kontekście są dostępne jako dodatkowe wbudowane zadania w skrypcie instalacyjnym.

directory_created(path)
file_created(path)

Te zadania powinny być uruchamiane gdy katalog lub plik jest tworzony przez skrypt poinstalacyjny w czasie instalacji. Zarejestruje on ścieżkę w programie odinstalowującym, tka, aby był usunięty gdy dystrybucja jest odinstalowywana. Dla bezpieczeństwa, katalogi są usuwane tylko, jeśli są puste.

get_special_folder_path(csidl_string)

To zadanie może być używane do pobierania szczególnych miejsc w Windows takich jak menu Start lub pulpit. Zwraca pełną ścieżkę dostępu do folderu. csidl_string musi być jednym z następujących ciągów znaków:

"CSIDL_APPDATA"

"CSIDL_COMMON_STARTMENU"
"CSIDL_STARTMENU"

"CSIDL_COMMON_DESKTOPDIRECTORY"
"CSIDL_DESKTOPDIRECTORY"

"CSIDL_COMMON_STARTUP"
"CSIDL_STARTUP"

"CSIDL_COMMON_PROGRAMS"
"CSIDL_PROGRAMS"

"CSIDL_FONTS"

Jeśli folder nie może być pobrany wyjątek OSError jest zgłaszany.

Which folders are available depends on the exact Windows version, and probably also the configuration. For details refer to Microsoft’s documentation of the SHGetSpecialFolderPath() function.

create_shortcut(target, description, filename[, arguments[, workdir[, iconpath[, iconindex]]]])

To zadanie tworzy skrót. cel ( - z ang. - target ) jest ścieżką do programu do uruchomienia przez skrót. description jest opisem skrótu. filename jest tytułem skrótu który użytkownik zobaczy. arguments określa parametry wiersza polecenia, jeśli jakieś mają wystąpić. workdir jest katalogiem roboczym dla programu. iconpath jest ścieżką dostępu do pliku zawierającego obrazek dla skrótu, zaś iconindex jest indeksem obrazka w pliku iconpath. Znów po więcej szczegółów zwróć się do dokumentacji Microsoftu pod hasłem sprzęgu IShellLink.

5.4. Kontrola Dostępu Użytkowników (UAC) z Visty

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).

Informacja

bdist_wininst is deprecated since Python 3.8.