# 5. Tworzenie Zbudowanych Dystrybucji

„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

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

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`. These installers can even be created on Unix platforms or Mac OS X.

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», «win-amd64» and «win-ia64». 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).