#
6 拡張モジュールのビルド: 小技と豆知識

Distutils は、可能なときにはいつでも、 setup.py スクリプトを 実行する Python インタプリタが提供する設定情報を使おうとします。 例えば、拡張モジュールをコンパイルする際には、コンパイラやリンカの フラグには Python をコンパイルした際と同じものが使われます。 通常、この設定はうまくいきますが、状況が複雑になると不適切な 設定になることもあります。この節では、通常の Distutils の動作を オーバライドする方法について議論します。

##
6.1 コンパイラ/リンカのフラグをいじるには

C や C++で書かれた Python 拡張をコンパイルする際、しばしば 特定のライブラリを使ったり、特定の種類のオブジェクトコードを 生成したりする上で、コンパイラやリンカに与えるフラグをカスタマイズ する必要があります。ある拡張モジュールが自分のプラットフォームでは テストされていなかったり、クロスコンパイルを行わねばならない 場合にはこれが当てはまります。

最も一般的なケースでは、拡張モジュールの作者はすでに 拡張モジュールのコンパイルが複雑になることを見越していて、 Setup ファイルを提供して編集できるようにしています。 Setup ファイルの編集は、モジュール配布物に多くの個別の拡張 モジュールがあったり、コンパイラに拡張モジュールをコンパイルさせる ために細かくフラグをセットする必要があるような場合にのみ行うことに なるでしょう。

Setup ファイルが存在する場合、ビルドするべき拡張モジュールの リストを得るために解釈されます。Setup ファイルの各行には 単一のモジュールを書きます。各行は以下のような構造をとります:

     module ... [sourcefile ...] [cpparg ...] [library ...]

次に、各フィールドについて見てみましょう。

- module はビルドする拡張モジュールの名前で、Python の 識別子名として有効でなければなりません。モジュールの名前変更は、 このフィールドを変えるだけではできない (ソースコードの編集も必要です) ので、このフィールドに手を加えるべきではありません。

- sourcefile は、少なくともファイル名から何の言語で書かれて いるかがわかるようになっているソースコードファイル名です。 .c で終わるファイルは C で書かれているとみなされ、 .C、.cc、および .c++ で終わるファイルは C++で書かれているとみなされます。.m や .mm で 終わるファイルは Objective C で書かれているとみなされます。

- cpparg は C プリプロセッサへの引数で、 -I、 -D、-U または -C のいずれかから始まる文字列です。

- library は .a で終わるか、 -l または -L のいずれかから始まる文字列です。

特定のプラットフォームにおいて、プラットフォーム上の特殊なライブラリ が必要な場合、 Setup ファイルを編集して `python setup.py build` を実行すればライブラリを追加できます。 例えば、以下の行

    foo foomodule.c

で定義されたモジュールを、自分のプラットフォーム上の数学ライブラリ libm.a とリンクしなければならない場合、Setup 内の 行に -lm を追加するだけです:

    foo foomodule.c -lm

コンパイラやリンカ向けの任意のスイッチオプションは、 -Xcompiler arg や -Xlinker arg オプションで与えます:

    foo foomodule.c -Xcompiler -o32 -Xlinker -shared -lm

-Xcompiler および -Xlinker の後にくる オプションは、それぞれ適切なコマンドラインに追加されます。 従って、上の例では、コンパイラには -o32 オプションが 渡され、リンカには -shared が渡されます。 コンパイラオプションに引数が必要な場合、複数の -Xcompiler オプションを与えます; 例えば、 `-x c++` を渡すには、 Setup ファイルには `-Xcompiler -x -Xcompiler c++` を渡さねばなりません。

コンパイラフラグは、環境変数 CFLAGS の設定でも与えられます。 CFLAGS が設定されていれば、Setup ファイル内で指定 されているコンパイラフラグに CFLAGS の内容が追加されます。

##
6.2 Windows で非 Microsoft コンパイラを使ってビルドするには

### 6.2.1 Borland C++

この小節では、 Borland C++ コンパイラのバージョン 5.5 で Distutils を使うために必要な手順について述べています。

まず、 Borland のオブジェクトファイル形式 (OMF) は、Python 公式サイトや ActiveState の Web サイトからダウンロード できるバージョンの Python が使っている形式とは違うことを知って おかねばなりません (Python は通常、 Microsoft Visual C++でビルド されています。Microsoft Visual C++は COFF をオブジェクトファイル 形式に使います。) このため、以下のようにして、 Python のライブラリ python20.lib を Borland の形式に変換する必要があります:

    coff2omf python20.lib python20_bcpp.lib

coff2omf プログラムは、 Borland コンパイラに付属しています。 python20.lib は Python インストールディレクトリの Libs ディレクトリ内にあります。拡張モジュールで他のライブラリ (zlib, ...) を使っている場合、それらのライブラリも変換しなければなりません。

変換されたファイルは、通常のライブラリと同じディレクトリに置かねば なりません。

さて、 Distutils は異なる名前を持つこれらのライブラリをどのように 扱うのでしょうか? 拡張モジュールで (例えば foo という名の) ライブラリが必要な場合、 Distutils はまず _bcpp が後ろに 付いたライブラリ (例えば foo_bcpp.lib) が見つかるかどうか 調べ、あればそのライブラリを使います。該当するライブラリがなければ、 デフォルトの名前 (foo.lib) を使います1。

Borland C++ を使って Distutils に拡張モジュールをコンパイル させるには、以下のように入力します:

    python setup.py build --compiler=bcpp

Borland C++ コンパイラをデフォルトにしたいなら、自分用、または システム全体向けに、 Distutils の設定ファイルを書くことを検討した 方がよいでしょう ( 5 節を参照してください)。

参考資料:

C++Builder Compiler
  Borland によるフリーの C++ コンパイラに関する情報で、 コンパイラのダウンロードページへのリンクもあります。

Creating Python Extensions Using Borland's Free Compiler
  Borland 製のフリーのコマンドライン C++ を使って Python を ビルドする方法について述べたドキュメントです。

### 6.2.2 GNU C / Cygwin / MinGW

この節では、 Cygwin や MinGW 2配布物中の GNU C/C++ コンパイラ で Distutils を使うために必要な手順について述べます。 Cygwin 向けにビルドされている Python インタプリタを使っているなら、 以下の手順をとらなくても Distutils はまったく問題なく動作します。

上記のコンパイラは、いくつかの特殊なライブラリを必要とします。 この作業は Borland の C++よりもやや複雑です。というのは、 ライブラリを変換するためのプログラムが存在しないからです。

まず、 Python DLL が公開している全てのシンボルからなるリストを 作成しなければなりません。 (この作業むけのプログラムは、 http://starship.python.net/crew/kernr/mingw32/Notes.htmlにあります。そのページで PExports 0.42h を探してください。)

    pexports python20.dll >python20.def

これで、上で得られた情報をもとに、 gcc 用の import ライブラリを作成 できます。

    dlltool --dllname python20.dll --def python20.def --output-lib libpython20.a

出来上がったライブラリは、 python20.lib と同じディレクトリ (Python インストールディレクトリの libs ディレクトリに なるはずです) に置かなければなりません。

拡張モジュールが他のライブラリ (zlib, ... ) を必要とする場合、 それらのライブラリも変換しなければなりません。 変換されたファイルは、それぞれ通常のライブラリが置かれているのと 同じディレクトリに置かねばなりません。

Cygwin を使って Distutils に拡張モジュールをコンパイルさせるには、

    python setup.py build --compiler=cygwin

のように入力します。また、非 cygwin モードの Cygwin 3 や MinGW では、

    python setup.py build --compiler=mingw32

のように入力します。

上記のオプションやコンパイラをデフォルトにしたいなら、自分用、または システム全体向けに、 Distutils の設定ファイルを書くことを検討した 方がよいでしょう ( 5 節を参照してください)。

参考資料:

Building Python modules on MS Windows platform with MinGW
  MinGW 環境で必要なライブラリのビルドに関する情報があります。

http://pyopengl.sourceforge.net/ftp/win32-stuff/
  Cygwin/MinGW および Borland 形式に変換済みの import ライブラリと、 Distutils がビルド済みの Python の場所を特定するために必要なレジストリ エントリを作成するためのスクリプトがあります。

... を使います 1
  つまり、全ての既存の COFF ライブラリを同名の OMF ライブラリに 置き換えてもかまわないということです
... MinGW 2
  詳しくは http://sources.redhat.com/cygwin/ や http://www.mingw.org/ を参照してください
... Cygwin 3
  このモードでは POSIX エミュレーションを利用できませんが、 cygwin1.dll も必要なくなります。