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

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

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

もちろん、モジュール開発者自身がパッケージ作成者かもしれません; また、
パッケージを作成するのはオリジナルの作成者が利用できないプラットフォー
ムにアクセスできるような "外部の" ボランティアかもしれませんし、ソース
配布物を定期的に取り込んで、アクセスできるかぎりのプラットフォーム向け
にビルド済み配布物を生成するソフトウェアかもしれません。作業を行うのが
誰であれ、パッケージ作成者は setup  スクリプトを利用し、 **bdist** コ
マンドファミリを使ってビルド済み配布物を作成します。

単純な例として、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)       |
|               | (".tar.gz")                    |           |
+---------------+--------------------------------+-----------+
| "bztar"       | bzip 圧縮された tar ファイル   |           |
|               | (".tar.bz2")                   |           |
+---------------+--------------------------------+-----------+
| "xztar"       | xzip 圧縮された tar ファイル   |           |
|               | (".tar.xz")                    |           |
+---------------+--------------------------------+-----------+
| "ztar"        | compress 圧縮された tar ファイ | (3)       |
|               | ル (".tar.Z")                  |           |
+---------------+--------------------------------+-----------+
| "tar"         | tar ファイル (".tar")          |           |
+---------------+--------------------------------+-----------+
| "zip"         | zip ファイル (".zip")          | (2),(4)   |
+---------------+--------------------------------+-----------+
| "rpm"         | RPM 形式                       | (5)       |
+---------------+--------------------------------+-----------+
| "pkgtool"     | Solaris **pkgtool** 形式       |           |
+---------------+--------------------------------+-----------+
| "sdux"        | HP-UX **swinstall** 形式       |           |
+---------------+--------------------------------+-----------+
| "wininst"     | Windows 用の自己展開形式 ZIP   | (4)       |
|               | ファイル                       |           |
+---------------+--------------------------------+-----------+
| "msi"         | マイクロソフト・インストーラー |           |
|               | 。                             |           |
+---------------+--------------------------------+-----------+

バージョン 3.5 で変更: "xztar" 形式のサポートが追加されました。

注釈:

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

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

3. 外部の **compress** ユーティリティが必要です。

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

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

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

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

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


5.1. 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.2. 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.3. 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.3.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.4. Vista のユーザアカウント制御 (UAC)
=======================================

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