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

注釈:

  このドキュメントは、
  https://setuptools.readthedocs.io/en/latest/setuptools.html にある
  "setuptools" のドキュメントが現時点でここにある関連情報を全て網羅す
  るまで、単独でここに載せておかれます。

"ビルド済み配布物" とは、おそらく皆さんが通常 "バイナリパッケージ" と
か "インストーラ" (背景にしている知識によって違います) と考えているも
のです。とはいえ、配布物が必然的にバイナリ形式になるわけではありません
。配布物には、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** 形式       |           |
+---------------+--------------------------------+-----------+
| "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_*** コマンドについては、以下の節で詳しく述べます。


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>"

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 でのクロスコンパイル
=================================

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

別のプラットフォーム向けのビルドを行うには、 "--plat-name" オプション
を指定します。現在のところ、有効な値は 'win32' と 'win-amd64' です。た
とえば、 32bit 版の Windows 上で、 以下のようにして 64bit版 Windows 向
けのビルドを行うことができます:

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

to build a 64bit version of your extension.

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

クロスコンパイルを行うためには、 Python のソースコードをダウンロードし
て Python 自身をターゲットのプラットフォーム向けにクロスコンパイルしな
ければなりません。 Python のバイナリインストールではクロスコンパイルで
きません (ターゲットのプラットフォーム用の .lib などのファイルが存在し
ないためです)。実際問題として、拡張モジュールのクロスコンパイルを可能
にするためには、32ビットOS のユーザーは Python ソースツリーの
"PCbuild/PCbuild.sln" ソリューションファイルを開き、 'pythoncore' プロ
ジェクトの "x64" コンフィグレーションをビルドするために Visual Studio
2008 を使う必要があるということを意味しています。

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


5.2.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 のドキュメントを参
   照してください。
