3. distutils による C および C++ 拡張モジュールのビルド
*******************************************************

Python 1.4 になってから、動的にリンクされるような拡張モジュールをビル
ドするためのメイクファイルを作成するような、特殊なメイクファイルをUnix
向けに提供するようになりました。Python 2.0 からはこの機構 (いわゆる
Makefile.pre.in および Setup ファイルの関係ファイル) はサポートされな
くなりました。インタプリタ自体のカスタマイズはほとんど使われず、
distutils で拡張モジュールをビルドできるようになったからです。

distutils を使った拡張モジュールのビルドには、ビルドを行う計算機上に
distutils をインストールしていることが必要です。Python 2.x には
distutils が入っており、Python 1.5 用には個別のパッケージがあります。
distutils はバイナリパッケージの作成もサポートしているので、ユーザが拡
張モジュールをインストールする際に、必ずしもコンパイラが必要というわけ
ではありません。

distutils ベースのパッケージには、駆動スクリプト (driver script) とな
る "setup.py" が入っています。 "setup.py" は普通の Python プログラムフ
ァイルで、ほとんどの場合以下のような内容になっています:

   from distutils.core import setup, Extension

   module1 = Extension('demo',
                       sources = ['demo.c'])

   setup (name = 'PackageName',
          version = '1.0',
          description = 'This is a demo package',
          ext_modules = [module1])

この "setup.py" とファイル "demo.c" があるとき、以下のコマンド

   python setup.py build

を実行すると、 "demo.c" をコンパイルして、 "demo" という名前の拡張モジ
ュールを "build" ディレクトリ内に生成します。システムによってはモジュ
ールファイルは "build/lib.system" サブディレクトリに生成され、
"demo.so" や "demo.pyd" といった名前になることがあります。

"setup.py" 内では、コマンドの実行はすべて "setup" 関数を呼び出して行い
ます。この関数は可変個のキーワード引数をとります。例ではその一部を使っ
ているにすぎません。もっと具体的にいうと、例の中ではパッケージをビルド
するためのメタ情報と、パッケージの内容を指定しています。通常、パッケー
ジには Python ソースモジュールやドキュメント、サブパッケージ等といった
別のファイルも入ります。 distutils の機能に関する詳細は、 Python モジ
ュールの配布 (レガシーバージョン) に書かれている distutils のドキュメ
ントを参照してください;  この節では、拡張モジュールのビルドについての
み説明します。

駆動スクリプトをよりよく構成するために、 "setup()" への引数を前もって
計算しておくことがよくあります。上の例では、 "setup()" の
"ext_modules" は拡張モジュールのリストで、リストの各々の要素は
"Extension" クラスのインスタンスになっています。上の例では、 "demo" と
いう名の拡張モジュールを定義していて、単一のソースファイル "demo.c" を
コンパイルしてビルドするよう定義しています。

多くの場合、拡張モジュールのビルドはもっと複雑になります。 というのは
、プリプロセッサ定義やライブラリの追加指定が必要になることがあるからで
す。 例えば以下のファイルがその実例です。

   from distutils.core import setup, Extension

   module1 = Extension('demo',
                       define_macros = [('MAJOR_VERSION', '1'),
                                        ('MINOR_VERSION', '0')],
                       include_dirs = ['/usr/local/include'],
                       libraries = ['tcl83'],
                       library_dirs = ['/usr/local/lib'],
                       sources = ['demo.c'])

   setup (name = 'PackageName',
          version = '1.0',
          description = 'This is a demo package',
          author = 'Martin v. Loewis',
          author_email = 'martin@v.loewis.de',
          url = 'https://docs.python.org/extending/building',
          long_description = '''
   This is really just a demo package.
   ''',
          ext_modules = [module1])

この例では、 "setup()" は追加のメタ情報と共に呼び出されます。配布パッ
ケージを構築する際には、メタ情報の追加が推奨されています。拡張モジュー
ル自体については、プリプロセッサ定義、インクルードファイルのディレクト
リ、ライブラリのディレクトリ、ライブラリといった指定があります。
distutils はこの情報をコンパイラに応じて異なるやり方で引渡します。例え
ば、Unix では、上の設定は以下のようなコンパイルコマンドになるかもしれ
ません

   gcc -DNDEBUG -g -O3 -Wall -Wstrict-prototypes -fPIC -DMAJOR_VERSION=1 -DMINOR_VERSION=0 -I/usr/local/include -I/usr/local/include/python2.2 -c demo.c -o build/temp.linux-i686-2.2/demo.o

   gcc -shared build/temp.linux-i686-2.2/demo.o -L/usr/local/lib -ltcl83 -o build/lib.linux-i686-2.2/demo.so

これらのコマンドラインは実演目的で書かれたものです; distutils のユーザ
は distutils が正しくコマンドを実行すると信用してください。


3.1. 拡張モジュールの配布
=========================

拡張モジュールをうまくビルドできたら、三通りの使い方があります。

エンドユーザは普通モジュールをインストールしようと考えます; これには、
次を実行します

   python setup.py install

モジュールメンテナはソースパッケージを作成します; これには、次を実行し
ます

   python setup.py sdist

場合によっては、ソース配布物に追加のファイルを含める必要があります; こ
れには "MANIFEST.in" ファイルを使います; 詳しくは distutils のドキュメ
ントを参照してください。

ソースコード配布物をうまく構築できたら、メンテナはバイナリ配布物も作成
できます。プラットフォームに応じて、以下のコマンドのいずれかを使います
。

   python setup.py bdist_wininst
   python setup.py bdist_rpm
   python setup.py bdist_dumb
