MacPythonについてのページ(よ)>

HOWTO: MPWでPythonモジュールをコンパイルする


Last modified at 2004/12/2

この文書はDr. Corran Websterさんによる"HOWTO: Compiling Python Modules with MPW"を訳したものです。
訳の公開に快く承諾してくださったDr. Corran Websterさんに感謝いたします。
内容の理解が伴っていないので、おかしいところがあるかもしれません。お気づきの点がございましたら、わたしまでお知らせいただければ幸いです。

Macintosh Programmer's Workshop (MPW) はApple社製の開発環境で、Developper CDあるいはAppleのFTPサイトから無料でダウンロード できます。

MPWのダウンロード、インストール方法については紹介マニアさんのページが詳しいです。

この文書の方法でモジュールをコンパイルできるのはPython1.5.2/2.0です。2.2.xだと、Python:Mac:Includeのpyconfig.h、Python:Includeのpyport.hとunicodeobject.hを訂正する必要があります。訳注として書いておきました。


Python programming languageMacintosh versionは ふつう、Metrowerks CodeWarriorでコンパイルされています。その結果、C拡張モジュールもたいていは CodeWarriorでコンパイルされており、ドキュメントとサンプルコードもCodeWarriorを念頭においた内容になっています。CodeWarriorは商用製品であり、趣味のハッカーの予算を越えたものかも知れません。 今ではたくさんのC拡張モジュールがMacintosh上でコンパイルされていますが、Macintoshのプラグインとしてディストリビューションに含まれてるものもあります。

Macintosh Programmer's Workshop (MPW) はApple社製の開発環境で、Developper CDあるいはAppleのFTPサイトから無料でダウンロード できます。Pythonは、CodeWarrirがMacOSの開発環境として優勢になる前に、もともとMPWで開発されたのでMPWのたいていの特質がすでにサポートされており、MPWでC拡張モジュールをコンパイルすることが可能です。

このHOWTOではPowerPC Macintosh用のコンパイルについて扱います。手順はcode fragment managerを使った68kMacintoshでも同様ですが、私は試したことがありません−私のold MacはNetBSDが走っているので。

このモジュールのコンパイル法はまだ実験的な段階です。下の注意のセクションを読んでください。

PythonモジュールのコンパイルのためにMPWをセットアップする

ここではすでにあなたがMacintoshにMPWとPythonのDeveloper's Kitのインストールに成功したと仮定します。

最初のステップはMPWにPythonがどこにあるかを知らせることです。このステップは必ずしも必要ではありませんが、開発を容易に、簡便にします。MPWのStartup ItemsフォルダにPythonという新しいファイルを作り、次のように書き込みます:

set Python "Macintosh HD:Applications:Python 1.5.2c1:"
set PythonIncludes "{Python}Include"
set PythonMacIncludes "{Python}Mac:Include"
set PythonCore "{Python}PythonCore"

export Python PythonIncludes PythonMacIncludes PythonCore

Macintosh HD:Applications:Python 1.5.2c1:は、実際にあなたのPythonが置かれているパスに置き換えて下さい。また、ほかの項目もヘッダーファイルとPythonCoreファイルの置かれている場所に置き換えてください。ここに示したのはPython 1.5.2c1の場合の一般的な場所ですが、Python 1.52b2や以前のバージョンの場合は違います(特に違っているのは、PythonCoreが機能拡張フォルダにあることです)。

訳注:以下の config.h の書き替えは MacPython1.5.2/2.0 で必要です。

次に、MPWのMrCコンパイラのためにconfig.hを書き直さなければなりません。このヘッダーファイルは標準のディストリビューションでは:Mac:Includeにあります。手入力で以下の行を、__MWERKS____SC__の似たような記述の後に加えます:

#ifdef __MRC__
#define BAD_STATIC_FORWARD
#endif

このステップは重要です:標準のディストリビューションに含まれる多くのモジュールは、この変更なしではコンパイルされません(下の問題点を参照)。

MPWのStartup itemのPythonconfig.hのコピーをここに置いておきますのでどうぞ。


訳注:MacPython2.2 では以下のやり方でできました。あまりきれいなやり方じゃないかもしれませんが。。。

(1):Include:pyport.hの148行目に以下の行を書き加えます。

#define DONT_HAVE_STAT
#define DONT_HAVE_FSTAT
#define DONT_HAVE_SYS_STAT_H
#undef HAVE_STAT_H
#define WITHOUT_FRAMEWORKS

(2):Include:unicodeobject.hの118行目をを削除、あるいはコメントアウトします。

/*#  include <wchar.h> */

(3)次に:Mac:Include:pyconfig.hの209行目

#define HAVE_USABLE_WCHAR_T 1

#define HAVE_USABLE_WCHAR_T 0

へ、

212行目

#define HAVE_WCHAR_H 1

#define HAVE_WCHAR_H 0

へ書き換えます。

さらに752行目

#define HAVE_UNISTD_H

を削除、あるいはコメントアウトします。

/* #define HAVE_UNISTD_H */

訳注終わり


もしUnixのモジュールをMacへ移植しているのなら、MPWのコピーの代わりにGUSIをインストールするのがいいかもしれません。GUSIはいくつかのPOSIX互換性を提供しており、Python自身によってこの目的のために使われています-最低限のヘッダーファイルだけでも便利です。Unixモジュールをポーティングしている人には注意なのですが、これを書いている時点での最も新しいMrCMrCppのアルファバージョンは、インクルードするのに-includes unixのコマンドラインオプションを入れることによってUnixスタイルのパス名が使用可能です。わたしはまだこれについてそんなに試していませんが、ゆくゆくは試すつもりですし、得られた結果をお知らせします。

これでモジュールをコンパイルするためのMPWとPythonのセットアップはできました。

モジュールをコンパイルする

C拡張モジュールのコンパイルの準備ができたと仮定します。モジュールの書き方についてはPythonドキュメントを見てください。

MPWでコンパイルするには3つのアプローチがあります。コマンドラインインターフェイスを使う、MPWのCreateMakeコマンド(メニュー項目の"Create build commandノ")を使う、Makefileを手書きする、の3つです。

これらのどの方法でも、始める前に知っておかなかればならないことがあります:

コマンドラインを使う

1つあるいは2つのCのファイルからなるシンプルなモジュールでは、MPWのワークシートでコマンドを使うのが便利です。ふつう、MPWのワーキングディレクトリをCのソースファイルがあるディレクトリにしたいでしょう。以下のコマンドで標準のPythonのテストモジュールxxmodule.cをコンパイルし、リンクします。

MrC "xxmodule.c" -o "xx.c.x" -w off  -d HAVE_CONFIG_H ∂
        -i "{PythonMacIncludes}" ∂
        -i "{PythonIncludes}" 
PPCLink ∂
        -o "xx.ppc.slb"  ∂
        "xx.c.x" ∂
        -t 'shlb' ∂
        -c 'Pyth' ∂
        -xm s ∂
        -d ∂
        "{PythonCore}" ∂
        "{SharedLibraries}InterfaceLib" ∂
        "{SharedLibraries}MathLib" ∂
        "{SharedLibraries}StdCLib" ∂
        "{PPCLibraries}StdCRuntime.o" ∂
        "{PPCLibraries}PPCCRuntime.o" ∂
        "{PPCLibraries}PPCToolLibs.o" ∂
        -export initxx

(注:各行の最後の文字は"partial derivative"のシンボルで、option-dでタイプでき、MPWの継続行を意味します。)

ヘッダーファイルを追加するには、MrCコマンドに-iオプションとディレクトリを加えます。shared libraryを加えるには、PPCLinkコマンドのPythonCoreライブラリの前に加えます。

2つ以上のソースファイルがあるときは、ソースファイルごとにコンパイルコマンドが必要で、PPCLinkコマンドにある"xx.c.x"のところですべてのオブジェクトファイルをインクルードします。

CreateMakeを使う

もっと込み入ったモジュールあるいは自分で書いたモジュールでは、たぶんmakefileを使いたいでしょう。残念ながら、MPWのmakefileは標準のUnixのmakefileと互換性がないので、モジュールのCのソースとともに配付されているmakefileを使うことはできません。

MPWのCreateMakeコマンドを使って makefileを作らなければなりません。(訳注:この段落を追記)

ふつうはCのソースコードと同じディレクトリにmakefileを置きたいので、先に進む前にMPWのワーキングディレクトリをCのソースコードのあるディレクトリに設定します。

標準のPythonのテストモジュールxxmodule.cのmakefileを作るには:

makefileができたら、編集する必要があります。カレントディレクトリの"xx.ppc.slb.make"ファイルを開いて、以下の変更をします:

ファイルを保存します。これでビルドする準備ができました。

"Build"あるいは"Full Build"メニューを選び、xx.ppc.slbとタイプすると、MPWがやってくれます。shared libraryをりビルドする必要がある時は、もう一度"Build"か"Full Build"をすればいいのです。

makefileを手書きする

ファイル間で込み入った依存性のある場合には、CreateMakeでビルドするより、もっと洗練されたmakefileが必要かも知れません。MPWのmakefileのフォーマットに馴染んでることが要求されるかもしれませんが、簡単な出発点としてCreateMakeを使うか、他のMPWのmakefileから出発する方法があります。

MPWのmakefileの概論について述べると、このHOWTOの範囲を越えます。MPWのMakeコマンドについてのドキュメントは、MPWのディストリビューションとともに、とくにBuilding and Maintaining Programs with MPW (2nd Edition)MPW Command Referenceにあります。

makefileを手書きする時に覚えておく重要なことが2つあります:

例としてここにxx.ppc.slb.makeを置いておきます。

拡張モジュールを使う

拡張モジュールをコンパイルしたら、Pythonにその場所を教えなければなりません。モジュールをPythonのサーチパス-例えば:Mac:Pluginsフォルダ-に移動してもいいですし、EditPythonPrefsアプレットを使って、モジュールのある場所をパスに加えることもできます。

これで作業は終わりではありません。たいていのモジュールはPythonによるラッパーを持っています。もしPythonのラッパーがなかったら、起動させるのにさらに手間がかかるかもしれません。そうしないと、Pythonの方でパイプなどのOS独自の機能を使う時には完全に書き直さなければならないかもしれません。それができるとしたらですが。

よくある問題点

モジュールを他のプラットフォームから移植した時によくある問題が2つあります。幸い、解決するのは簡単です。

Staticがすでに定義されているStatic Forward Definitions

もしこのようなコンパイルエラーが表示されたら:

File "xxmodule.c"; line 135 #Error: 'Xxo_Type' is already defined

この場合はおそらくconfig.hを設定してなくて、static forward definitionsを正しく扱えないからか、モジュールの作者がPythonの標準の決まりを守っていないかのどちらかです。後者なら、変数が最初に定義されている場所をみつけて、staticstaticforwardで置き換えます。そして2回目に定義されている場所をみつけて(多くの場合、コンパイラが指摘した行です)、staticstatichereで置き換えます。

正しく設定したら、今度はコンパイルできるはずです。

自動型変換Automatic Type Conversion

あるタイプから他のタイプへ自動的に変換する場合、MrCは他のCコンパイラと比べて少し気難しいようです。他のコンパイラでは、明示的な型キャストを単純に加えることにより、目的のタイプへ変換されます。

XXX これを楽にできるコンパイラのオプションがあれば、いい解決になるのに。

注意

Jack JansenがMac Pythonメーリングリストで指摘したように、MetroWerksのCルーチンでコンパイルされたPythonCoreや標準モジュールと、MPWのCルーチンでコンパイルされた自作の拡張モジュールとの間に潜在的なコンフリクトがあったようです。日常の使用でうまくいっていても、まだ見つかっていないバグがある可能性があります。これはたいていCの関数が期待されたように働かない(よくあるのはI/O関数で、SIOUXとSIOWのライブラリの間のコンフリクトによる)とか、誤ったmalloc/freeによるメモリリークという形で現れます。

このような問題は、StdCLibの後にリンクしたPythonCoreでモジュールをコンパイルした時(この設定ではprintfは正しく働きません)に起こっています。また、モジュールがメモリを割り当ててPythonが後から片付ける場合、あるいはその逆の場合にmalloc/freeの問題があるかもしれないと、疑っています。StdClibより先にPythonCoreを置いてコンパイルすると、正しい結果が得られるようです。

このコンパイル法は、現時点では実験段階だと考えるべきです。あなたの責任において使用してください。

この方法でコンパイルしたモジュールで何か気付いたり、うまくいかない、うまくいくというような方法に気付いたら、私にお知らせ下さい。HOWTOに加えることができます。

この問題の理想的な解決法があれば、MPWを使ってPythonをコンパイルできるようになります(そして、Python MPWツールはとても素晴らしいものになります)。しかし、これは大きなプロジェクトになるでしょう。