5. ビルド済み配布物を作成する
*****************************

"ビルド済み配布物" とは、おそらく皆さんが通常 "バイナリパッケージ" と
か "インストーラ" (背景にしている知識によって違います) と考えているも
のです。とはいえ、配布物が必然的にバイナリ形式になるわけではありません
。配布物には、Python ソースコード、かつ/またはバイトコードが入るからで
す; また、我々はパッケージという呼び方もしません。すでに Python の用語
として使っているからです (また、"インストーラ" という言葉は主流のデス
クトップシステム特有の用語です)

ビルド済み配布物は、モジュール配布物をインストール作業者にとってできる
だけ簡単な状況にする方法です: ビルド済み配布物は、RPM ベースの Linux
システムユーザにとってはバイナリ RPM、Windows ユーザにとっては実行可能
なインストーラ、Debian ベースの Linux システムでは Debian パッケージ、
などといった具合です。当然のことながら、一人の人間が世の中にある全ての
プラットフォーム用にビルド済み配布物を作成できるわけではありません。そ
こで、Distutils の設計は。開発者が自分の専門分野 --- コードを書き、ソ
ース配布物を作成する --- に集中できる一方で、*パッケージ作成者
(packager)* と呼ばれる、開発者とエンドユーザとの中間に位置する人々がソ
ースコード配布物を多くのプラットフォームにおけるビルド済み配布物に変換
できるようになっています。

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.

単純な例として、Distutils ソースツリーから以下のコマンドを実行したとし
ます:

   python setup.py bdist

すると、Distutils はモジュール配布物 (ここでは Distutils 自体) をビル
ドし、"偽の (fake)" インストールを ("build" ディレクトリで) 行います。
そして現在のプラットフォームにおける標準の形式でビルド済み配布物を生成
します。デフォルトのビルド済み形式とは、Unixでは "ダム (dumb)" の tar
ファイルで、 Windows ではシンプルな実行形式のインストーラになります。
(tar ファイルは、特定の場所に手作業で解凍しないと動作しないので、 "ダ
ム: 賢くない" 形式とみなします。)

従って、 Unix システムで上記のコマンドを実行すると、
"Distutils-1.0.*plat*.tar.gz" を作成します;  この tarball を正しい場所
で解凍すると、ちょうどソース配布物をダウンロードして "python setup.py
install" を実行したのと同じように、正しい場所に Distutils がインストー
ルされます。 ("正しい場所 (right place)" とは、ファイルシステムのルー
ト下か、 Python の "*prefix*" ディレクトリ下で、これは **bdist_dumb**
に指定するコマンドで変わります; デフォルトの設定では、 "*prefix*" から
の相対パスにインストールされるダム配布物が得られます。)

言うまでもなく、pure Python 配布物の場合なら、"python setup.py
install" するのに比べて大して簡単になったとは言えません---しかし、非
pure 配布物で、コンパイルの必要な拡張モジュールを含む場合、拡張モジュ
ールを利用できるか否かという大きな違いになりえます。また、RPM パッケー
ジや Windows 用の実行形式インストーラのような "スマートな" ビルド済み
配布物を作成しておけば、たとえ拡張モジュールが一切入っていなくてもユー
ザにとっては便利になります。

**bdist** コマンドには、 "--formats" オプションがあります。これは
**sdist** コマンドの場合に似ていて、生成したいビルド済み配布物の形式を
選択できます: 例えば、

   python setup.py bdist --format=zip

とすると、Unix システムでは、 "Distutils-1.0.*plat*.zip" を作成します
--- 先にも述べたように、Distutils をインストールするには、このアーカイ
ブ形式をルートディレクトリ下で展開します。

ビルド済み配布物として利用できる形式を以下に示します:

+---------------+--------------------------------+-----------+
| フォーマット  | 説明                           | 注釈      |
+===============+================================+===========+
| "gztar"       | gzip 圧縮された tar ファイル   | (1),(3)   |
|               | (".tar.gz")                    |           |
+---------------+--------------------------------+-----------+
| "ztar"        | compress 圧縮された tar ファイ | (3)       |
|               | ル (".tar.Z")                  |           |
+---------------+--------------------------------+-----------+
| "tar"         | tar ファイル (".tar")          | (3)       |
+---------------+--------------------------------+-----------+
| "zip"         | zip ファイル (".zip")          | (2),(4)   |
+---------------+--------------------------------+-----------+
| "rpm"         | RPM 形式                       | (5)       |
+---------------+--------------------------------+-----------+
| "pkgtool"     | Solaris **pkgtool** 形式       |           |
+---------------+--------------------------------+-----------+
| "sdux"        | HP-UX **swinstall** 形式       |           |
+---------------+--------------------------------+-----------+
| "wininst"     | Windows 用の自己展開形式 ZIP   | (4)       |
|               | ファイル                       |           |
+---------------+--------------------------------+-----------+
| "msi"         | マイクロソフト・インストーラー |           |
|               | 。                             |           |
+---------------+--------------------------------+-----------+

注釈:

1. Unixでのデフォルト形式です

2. Windows でのデフォルト形式です

3. 外部ユーティリティが必要です: **tar** と、 **gzip** または
   **bzip2** または **compress** のいずれか

4. 外部ユーティリティの **zip** か、 "zipfile" モジュール (Python
   1.6 からは標準 Python ライブラリの一部になっています) が必要です

5. 外部ユーティリティの **rpm** 、バージョン 3.0.4 以上が必要です (
   バ ージョンを調べるには、 "rpm --version" とします)

**bdist** コマンドを使うとき、必ず "--formats"  オプションを使わなけれ
ばならないわけではありません; 自分の使いたい形式をダイレクトに実装して
いるコマンドも使えます。こうした **bdist** "サブコマンド (sub-
command)" は、実際には類似のいくつかの形式を生成できます; 例えば、
**bdist_dumb** コマンドは、全ての "ダム" アーカイブ形式 ("tar",
"ztar", "gztar", および "zip") を作成できますし、 **bdist_rpm** はバイ
ナリ RPM とソース RPM の両方を生成できます。 **bdist** サブコマンドと
、それぞれが生成する形式を以下に示します:

+----------------------------+-------------------------+
| コマンド                   | Formats                 |
+============================+=========================+
| **bdist_dumb**             | tar, ztar, gztar, zip   |
+----------------------------+-------------------------+
| **bdist_rpm**              | rpm, srpm               |
+----------------------------+-------------------------+
| **bdist_wininst**          | wininst                 |
+----------------------------+-------------------------+
| **bdist_msi**              | msi                     |
+----------------------------+-------------------------+

**bdist_*** コマンドについては、以下の節で詳しく述べます。


5.1. “ダム (dumb)” 形式のビルド済み配布物を作成する
===================================================


5.2. RPM パッケージを作成する
=============================

RPM 形式は、Red Hat, SuSE, Mandrake といった、多くの一般的な Linux デ
ィストリビューションで使われています。普段使っているのがこれらの環境の
いずれか (またはその他の RPM ベースの Linux  ディストリビューション)
なら、同じディストリビューションを使っている他のユーザ用に 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"

Distutils が setup スクリプトで制御されているのとほとんど同じく、 RPM
パッケージの作成は、 ".spec" で制御されています。 RPM の作成を簡便に解
決するため、 **bdist_rpm** コマンドでは通常、 setup スクリプトに与えた
情報とコマンドライン、そして Distutils 設定ファイルに基づいて ".spec"
ファイルを作成します。 ".spec" ファイルの様々なオプションやセクション
情報は、以下のようにして setup スクリプトから取り出されます:

+--------------------------------------------+------------------------------------------------+
| RPM ".spec" ファイルのオプションまたはセク | Distutils setup スクリプト内のオプション       |
| ション                                     |                                                |
+============================================+================================================+
| 名前                                       | "name"                                         |
+--------------------------------------------+------------------------------------------------+
| Summary (preamble 内)                      | "description"                                  |
+--------------------------------------------+------------------------------------------------+
| Version                                    | "version"                                      |
+--------------------------------------------+------------------------------------------------+
| Vendor                                     | "author" と "author_email", または  --- &      |
|                                            | "maintainer" と "maintainer_email"             |
+--------------------------------------------+------------------------------------------------+
| Copyright                                  | "license"                                      |
+--------------------------------------------+------------------------------------------------+
| Url                                        | "url"                                          |
+--------------------------------------------+------------------------------------------------+
| %description (section)                     | "long_description"                             |
+--------------------------------------------+------------------------------------------------+

また、 ".spec" ファイル内の多くのオプションは、 setup スクリプト中に対
応するオプションがありません。これらのほとんどは、以下に示す
**bdist_rpm** コマンドのオプションで扱えます:

+---------------------------------+-------------------------------+---------------------------+
| RPM ".spec" ファイルのオプショ  | **bdist_rpm** オプション      | デフォルト値              |
| ンまたはセクション              |                               |                           |
+=================================+===============================+===========================+
| リリース                        | "release"                     | "1"                       |
+---------------------------------+-------------------------------+---------------------------+
| Group                           | "group"                       | "Development/Libraries"   |
+---------------------------------+-------------------------------+---------------------------+
| Vendor                          | "vendor"                      | (上記参照)                |
+---------------------------------+-------------------------------+---------------------------+
| Packager                        | "packager"                    | (none)                    |
+---------------------------------+-------------------------------+---------------------------+
| Provides                        | "provides"                    | (none)                    |
+---------------------------------+-------------------------------+---------------------------+
| Requires                        | "requires"                    | (none)                    |
+---------------------------------+-------------------------------+---------------------------+
| Conflicts                       | "conflicts"                   | (none)                    |
+---------------------------------+-------------------------------+---------------------------+
| Obsoletes                       | "obsoletes"                   | (none)                    |
+---------------------------------+-------------------------------+---------------------------+
| Distribution                    | "distribution_name"           | (none)                    |
+---------------------------------+-------------------------------+---------------------------+
| BuildRequires                   | "build_requires"              | (none)                    |
+---------------------------------+-------------------------------+---------------------------+
| Icon                            | "icon"                        | (none)                    |
+---------------------------------+-------------------------------+---------------------------+

明らかに、これらのオプションの中からいくつかだけを提供することでさえ、
退屈で間違いを起こしやすいものでしょう。なので通常は、それらを setup
設定ファイル "setup.cfg" に収めるのが最適な方法です --- setup 設定ファ
イル (setup configuration file) を書く を参照してください。多くの
Python モジュールの配布物を頒布したりパッケージングする場合は、それら
全てに適用するオプションをあなた専用の Distutils 設定ファイル
("~/.pydistutils.cfg") に収めたいと思うかもしれません。このファイルを
一時的に無効にしたければ、 "--no-user-cfg" を "setup.py" に渡せます。

バイナリ形式の RPM パッケージを作成する際には三つの段階があり、
Distutils はこれら全ての段階を自動的に処理します:

1. RPM パッケージの内容を記述する ".spec" ファイルを作成します
   (".spec" ファイルは setup スクリプトに似たファイルです; 実際、
   setup スクリプトのほとんどの情報が ".spec" ファイルから引き揚げられ
   ます)

2. ソース RPM を作成します

3. "バイナリ (binary)" RPM を生成します (モジュール配布物に Python
   拡 張モジュールが入っているか否かで、バイナリコードが含まれることも
   含 まれないこともあります)

通常、RPM は最後の二つのステップをまとめて行います; Distutils を使うと
、普通は三つのステップ全てをまとめて行います。

望むなら、これらの三つのステップを分割できます。 **bdist_rpm**  コマン
ドに "--spec-only" を指定すれば、単に ".spec" を作成して終了します; こ
の場合、 ".spec" ファイルは "配布物ディレクトリ (distribution
directory)"--- 通常は "dist/" に作成されますが、 "--dist-dir" オプショ
ンで変更することもできます。(通常、 ".spec" ファイルは "ビルドツリー
(build tree)"、すなわち **bdist_rpm** が作成する一時ディレクトリの中か
ら引き揚げられます。)


5.3. Windows インストーラを作成する
===================================

実行可能なインストーラは、Windows 環境ではごく自然なバイナリ配布形式で
す。インストーラは結構なグラフィカルユーザインタフェースを表示して、モ
ジュール配布物に関するいくつかの情報を setup スクリプト内のメタデータ
から取り出して示し、ユーザがいくつかのオプションを選んだり、インストー
ルを決行するか取りやめるか選んだりできるようにします。

メタデータは setup スクリプトから取り出されるので、Windows インストー
ラの作成は至って簡単で、以下を実行するだけです:

   python setup.py bdist_wininst

あるいは、 **bdist** コマンドを "--formats" オプション付きで実行します
:

   python setup.py bdist --formats=wininst

(pure Python モジュールとパッケージだけの入った) pure モジュール配布物
の場合、作成されるインストーラは実行バージョンに依存しない形式になり、
"foo-1.0.win32.exe" のような名前になります。 pure モジュールの Windows
インストーラは Unix や Mac OS X でも作成できます。

非 pure 配布物の場合、拡張モジュールは Windows プラットフォーム上だけ
で作成でき、Python のバージョンに依存したインストーラになります。イン
ストーラのファイル名もバージョン依存性を反映して、
"foo-1.0.win32-py2.0.exe" のような形式になります。従って、サポートした
い全てのバージョンの Python に対して、別々のインストーラを作成しなけれ
ばなりません。

インストーラは、ターゲットとなるシステムにインストールを実行した後、
pure モジュールを通常 (normal) モードと最適化 (optimizing) モードでバ
イトコード(*bytecode*)にコンパイルしようと試みます。何らかの理由があっ
てコンパイルさせたくなければ、 **bdist_wininst** コマンドを "--no-
target-compile" かつ/または "--no-target-optimize" オプション付きで実
行します。

デフォルトでは、インストーラは実行時にクールな "Python Powered" ロゴを
表示しますが、自作の152x261ビットマップ画像も指定できます。画像は
Windows の ".bmp" ファイル形式でなくてはならず、 "--bitmap" オプション
で指定します。

インストーラを起動すると、デスクトップの背景ウィンドウ上にでっかいタイ
トルも表示します。タイトルは配布物の名前とバージョン番号から作成します
。 "--title" オプションを使えば、タイトルを別のテキストに変更できます
。

インストーラファイルは "配布物ディレクトリ (distribution directory)"
--- 通常は "dist/" に作成されますが、 "--dist-dir" オプションで指定す
ることもできます。


5.4. Windows でのクロスコンパイル
=================================

Python 2.6 から、distutils は Windows プラットフォーム間でのクロスコン
パイルに対応しました。これによって、必要なツールがインストールされてい
れば、32bit 版の Windows で 64bit 版の拡張を作成したり、その逆が可能に
なりました。

別のプラットフォーム用にビルドするには、 build コマンドの "--plat-
name" オプションを指定します。有効な値は、現在のところ、 'win32',
'win-amd64', 'win-ia64' です。例えば、次のようにして 32bit 版の
Windows で 64bit 版の拡張をビルドできます:

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

Windows インストーラもこのオプションをサポートしています。なので次のコ
マンドを実行すると:

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

64bit のインストーラを32bitのWindowsで作成できます。

クロスコンパイルするためには、Python のソースコードをダウンロードして
Python 自体をターゲットのプラットフォーム用にクロスコンパイルしなけれ
ばなりません。 Python のバイナリインストールからではクロスコンパイルで
きません。(他のプラットフォーム用の .lib などのファイルが含まれないか
らです。) 具体的に言えば、拡張のクロスコンパイルができるようになるには
、 32bit OS のユーザーは Visual Studio 2008 を使って Python ソースツリ
ー内の "PCBuild/PCbuild.sln" ソリューションファイルを開き、 "x64" コン
フィギュレーションで 'pythoncore' プロジェクトをビルドしなければなりま
せん。

デフォルトでは、Visual Studio 2008 は 64bit のコンパイラーなどのツール
をインストールしないことに注意してください。Visual Studio セットアップ
プロセスを再実行して、それらのツールを選択する必要があるでしょう。(コ
ントロールパネル -> [追加と削除] から簡単に既存のインストールをチェッ
ク、修正できます。)


5.4.1. インストール後実行スクリプト (postinstallation script)
-------------------------------------------------------------

Python 2.3 からは、インストール実行後スクリプトを "--install-script"
オプションで指定できるようになりました。スクリプトはディレクトリを含ま
ないベースネーム (basename) で指定しなければならず、スクリプトファイル
名は setup 関数の scripts 引数中に挙げられていなければなりません。

指定したスクリプトは、インストール時、ターゲットとなるシステム上で全て
のファイルがコピーされた後に実行されます。このとき "argv[1]" を
"-install" に設定します。また、アンインストール時には、ファイルを削除
する前に "argv[1]" を "-remove" に設定して実行します。

Windows インストーラでは、インストールスクリプトは埋め込みで実行され、
全ての出力 ("sys.stdout"、"sys.stderr") はバッファにリダイレクトされ、
スクリプトの終了後に GUI 上に表示されます。

インストールスクリプトでは、インストール/アンインストールのコンテキス
トで特に有用ないくつかの機能を、追加の組み込み関数として利用することが
できます。

directory_created(path)
file_created(path)

   これらの関数は、インストール後実行スクリプトがディレクトリやファイ
   ルを作成した際に呼び出さなければなりません。この関数はアンインスト
   ーラに作成された *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 のバージョンごと
   に異なります。また、おそらく設定によっても異なるでしょう。詳細につ
   いては、 "SHGetSpecialFolderPath()" 関数に関する Microsoft のドキュ
   メントを参照してください。

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

   この関数はショートカットを作成します。 *target* はショートカットに
   よって起動されるプログラムへのパスです。 *description* はショートカ
   ットに対する説明です。 *filename* はユーザから見えるショートカット
   の名前です。コマンドライン引数があれば、 *arguments* に指定します。
   *workdir* はプログラムの作業ディレクトリです。 *iconpath* はショー
   トカットのためのアイコンが入ったファイルで、 *iconindex* はファイル
   *iconpath* 中のアイコンへのインデクスです。これについても、詳しくは
   "IShellLink" インタフェースに関する Microsoft のドキュメントを参照
   してください。


5.5. Vista のユーザアカウント制御 (UAC)
=======================================

Python 2.6 から、 bdist_wininst は "--user-access-control" オプション
をサポートしています。デフォルトは 'none' (UAC制御をしないことを意味し
ます) で、それ以外の有効な値は 'auto' (Python が全ユーザー用にインスト
ールされていれば UAC 昇格を行う)、 'force' (常に昇格を行う) です。
