.. _built-dist:

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

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

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

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

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

   python setup.py bdist

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

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

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

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

   python setup.py bdist --format=zip

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

.. %

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

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

注記:

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

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

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

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

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

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

+--------------------------+-----------------------+
| コマンド                 | 形式                  |
+==========================+=======================+
| :command:`bdist_dumb`    | tar, ztar, gztar, zip |
+--------------------------+-----------------------+
| :command:`bdist_rpm`     | rpm, srpm             |
+--------------------------+-----------------------+
| :command:`bdist_wininst` | wininst               |
+--------------------------+-----------------------+
| :command:`bdist_msi`     | msi                   |
+--------------------------+-----------------------+

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


.. _creating-dumb:

ダム形式のビルド済み配布物を作成する
====================================

.. XXX 絶対パスと相対パスのパッケージについて述べる必要があるんだけど、
       その前に実装しなくちゃね！


.. _creating-rpms:

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

RPM 形式は、Red Hat, SuSE, Mandrake といった、多くの一般的な Linux
ディストリビューションで使われています。普段使っているのがこれらの環境のいずれか (またはその他の RPM ベースの Linux  ディストリビューション)
なら、同じディストリビューションを使っている他のユーザ用に RPM パッケージを作成するのはとるに足らないことでしょう。一方、モジュール配布物の複雑さや、
Linux ディストリビューション間の違いにもよりますが、他の RPM ベースのディストリビューションでも動作するような RPM
を作成できるかもしれません。

通常、モジュール配布物の RPM を作成するには、 :command:`bdist_rpm`  コマンドを使います::

   python setup.py bdist_rpm

あるいは、 :command:`bdist` コマンドを :option:`--format`  オプション付きで使います::

   python setup.py bdist --formats=rpm

前者の場合、 RPM 特有のオプションを指定できます; 後者の場合、一度の実行で複数の形式を指定できます。両方同時にやりたければ、
それぞれの形式について各コマンドごとにオプション付きで :command:`bdist_\*` コマンドを並べます::

   python setup.py bdist_rpm --packager="John Doe <jdoe@example.org>" \
                   bdist_wininst --target-version="2.0"

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

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

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

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

言うまでもなく、こうしたオプションをコマンドラインで指定するのは面倒だし、エラーの元になりますから、普通は :file:`setup.cfg` に
書いておくのがベストです ---  :ref:`setup-config` 節を参照してください。沢山の Python
モジュール配布物を配布したりパッケージ化したりしているのなら、配布物全部に当てはまるオプションを個人用の Distutils 設定ファイル
(:file:`~/.pydistutils.cfg`) に入れられます。
このファイルを一時的に無効にしたい場合、 setup.py に --no-user-cfg オプションを指定できます。

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

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

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

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

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

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

.. % \XXX{この機能はまだ実装されていません---必要なの?!}
.. % 自作の \file{.spec} ファイルを \longprogramopt{spec-file} オプションで
.. % 指定することもできます; \longprogramopt{spec-only} と併せて利用すれば、
.. % \file{.spec} ファイルを手作業でカスタマイズする機会が生まれます:
.. %
.. % begin{verbatim}
.. % > python setup.py bdist_rpm --spec-only
.. % # ... dist/FooBar-1.0.spec を編集
.. % > python setup.py bdist_rpm --spec-file=dist/FooBar-1.0.spec
.. % end{verbatim}
.. %
.. % (とはいえ、\file{.spec} の内容をカスタマイズしたいのなら、
.. % 標準の \command{bdist\_rpm} を上書きして、自分の思い通りに
.. % \file{.spec} ファイルを書かせる方がおそらくましでしょう。)


.. _creating-wininst:

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

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

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

   python setup.py bdist_wininst

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

   python setup.py bdist --formats=wininst

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

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

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

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

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

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

.. _cross-compile-windows:

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

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

別のプラットフォーム用にビルドするには、 build コマンドの :option:`--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 ソースツリー内の
:file:`PCBuild/PCbuild.sln` ソリューションファイルを開き、
"x64" コンフィギュレーションで 'pythoncore' プロジェクトをビルドしなければなりません。

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

.. _postinstallation-script:

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

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

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

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

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


.. function:: directory_created(path)
              file_created(path)

   これらの関数は、インストール後実行スクリプトがディレクトリやファイルを作成した際に呼び出さなければなりません。この関数はアンインストーラ
   に作成された *path* を登録し、配布物をアンインストールする際にファイルが消されるようにします。安全を期すために、ディレクトリは空の時にのみ削除されます。


.. function:: 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"

   該当するフォルダを取得できなかった場合、 :exc:`OSError` が送出されます。

   どの種類のフォルダを取得できるかは、特定の Windows のバージョンごとに異なります。また、おそらく設定によっても異なるでしょう。詳細については、
   :c:func:`SHGetSpecialFolderPath` 関数に関する Microsoft のドキュメントを参照してください。



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

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


Vista User Access Control (UAC)
===============================

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