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 languageの Macintosh 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が走っているので。
このモジュールのコンパイル法はまだ実験的な段階です。下の注意のセクションを読んでください。
ここではすでにあなたが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のPython
とconfig.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モジュールをポーティングしている人には注意なのですが、これを書いている時点での最も新しいMrC
とMrCpp
のアルファバージョンは、インクルードするのに-includes unix
のコマンドラインオプションを入れることによってUnixスタイルのパス名が使用可能です。わたしはまだこれについてそんなに試していませんが、ゆくゆくは試すつもりですし、得られた結果をお知らせします。
これでモジュールをコンパイルするためのMPWとPythonのセットアップはできました。
C拡張モジュールのコンパイルの準備ができたと仮定します。モジュールの書き方についてはPythonドキュメントを見てください。
MPWでコンパイルするには3つのアプローチがあります。コマンドラインインターフェイスを使う、MPWのCreateMake
コマンド(メニュー項目の"Create build commandノ")を使う、Makefileを手書きする、の3つです。
これらのどの方法でも、始める前に知っておかなかればならないことがあります:
xxmodule.c
という名前で、MPWのカレントワーキングディレクトリにあるとします。xx
で、shared libraryファイルの名前はxx.ppc.slb
となります。init
で始まります。例ではinitxx
です。
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"
のところですべてのオブジェクトファイルをインクルードします。
もっと込み入ったモジュールあるいは自分で書いたモジュールでは、たぶんmakefileを使いたいでしょう。残念ながら、MPWのmakefileは標準のUnixのmakefileと互換性がないので、モジュールのCのソースとともに配付されているmakefileを使うことはできません。
MPWのCreateMakeコマンドを使って makefileを作らなければなりません。(訳注:この段落を追記)
ふつうはCのソースコードと同じディレクトリにmakefileを置きたいので、先に進む前にMPWのワーキングディレクトリをCのソースコードのあるディレクトリに設定します。
標準のPythonのテストモジュールxxmodule.c
のmakefileを作るには:
makefileができたら、編集する必要があります。カレントディレクトリの"xx.ppc.slb.make"ファイルを開いて、以下の変更をします:
Includes =
変更後
Includes = -i "{PythonIncludes}" -i "{PythonMacIncludes}"
もし、ヘッダーファイルを加えるなら、同じようにここでインクルードする必要があります。
PPCCOptions = {Includes} {Sym•PPC}
変更後
PPCCOptions = -w off -d HAVE_CONFIG_H {Includes} {Sym•PPC}
-xm s ∂
以下を加えます。
-d ∂ "{PythonCore}" ∂
他のshared libraryにリンクする必要があるなら、PythonCoreの前の行に追記し、その各行をそれぞれ∂
で終えます。
ファイルを保存します。これでビルドする準備ができました。
"Build"あるいは"Full Build"メニューを選び、xx.ppc.slbとタイプすると、MPWがやってくれます。shared libraryをりビルドする必要がある時は、もう一度"Build"か"Full Build"をすればいいのです。
ファイル間で込み入った依存性のある場合には、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つあります:
PPCLink
コマンドの引数のうちで最初にあるファイルのシンボルが使われます。このため、標準のランタイムlibraryの前に出てくるMPW標準のランタイムenvironmentではなく、PythonCoreと他のshared libararyをふつうは使いたいでしょう。とくにStdCLibの場合はそうです。"-d"オプションにより、たくさんのシンボルに関する(しばしばたくさんの)警告をオフにできます。MrC
にHAVE_CONFIG_H
のプリプロセッサーシンボルを-d HAVE_CONFIG_H
オプションによって確実に定義したいでしょう。
例としてここにxx.ppc.slb.make
を置いておきます。
拡張モジュールをコンパイルしたら、Pythonにその場所を教えなければなりません。モジュールをPythonのサーチパス-例えば:Mac:Plugins
フォルダ-に移動してもいいですし、EditPythonPrefs
アプレットを使って、モジュールのある場所をパスに加えることもできます。
これで作業は終わりではありません。たいていのモジュールはPythonによるラッパーを持っています。もしPythonのラッパーがなかったら、起動させるのにさらに手間がかかるかもしれません。そうしないと、Pythonの方でパイプなどのOS独自の機能を使う時には完全に書き直さなければならないかもしれません。それができるとしたらですが。
モジュールを他のプラットフォームから移植した時によくある問題が2つあります。幸い、解決するのは簡単です。
もしこのようなコンパイルエラーが表示されたら:
File "xxmodule.c"; line 135 #Error: 'Xxo_Type' is already defined
この場合はおそらくconfig.h
を設定してなくて、static forward definitionsを正しく扱えないからか、モジュールの作者がPythonの標準の決まりを守っていないかのどちらかです。後者なら、変数が最初に定義されている場所をみつけて、static
をstaticforward
で置き換えます。そして2回目に定義されている場所をみつけて(多くの場合、コンパイラが指摘した行です)、static
をstatichere
で置き換えます。
正しく設定したら、今度はコンパイルできるはずです。
あるタイプから他のタイプへ自動的に変換する場合、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ツールはとても素晴らしいものになります)。しかし、これは大きなプロジェクトになるでしょう。