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

「ビルド済み配布物」 とは、おそらく皆さんが通常 「バイナリパッケージ」
とか 「インストーラ」 (背景にしている知識によって違います) と考えてい
るものです。とはいえ、配布物が必然的にバイナリ形式になるわけではありま
せん。配布物には、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),(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. requires external utilities: **tar** and possibly one of
   **gzip**, **bzip2**, or **compress**

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

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

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", "ztar", "gztar", and "zip"), and **bdist_rpm** generates both
binary and source RPMs.  The **bdist** sub-commands, and the formats
generated by each, are:

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

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


Creating dumb built distributions
=================================


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

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 setup 設定ファイ
ル (setup configuration file) を書く.  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.

バイナリ形式の 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** が作成する一時ディレクトリの中
から引き揚げられます。)


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" オプションで指定する
こともできます。


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 セットアップ
プロセスを再実行して、それらのツールを選択する必要があるでしょう。(コ
ントロールパネル -> [追加と削除] から簡単に既存のインストールをチェッ
ク、修正できます。)


インストール後実行スクリプト (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 のドキュメントを参照
   してください。


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

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