PowerPC MacからApple Siliconまで、クラシックなMac体験を届けるアプリを配布しています。なぜまだ使えるMacを捨てるのか。究極のエコは使い続けること。
PowerPC Tiger向けにビルドしたCPython 3.12.11 + pipです。再配置可能(好きな場所に置けます)。 python.org公式ビルドではない個人ビルドです。調べた限り、Python 3.12とTigerの組み合わせに前例は見当たりませんでした(3.10/3.11はMacPorts/Tigerbrewコミュニティ経由でLeopard向けにありますが、 Tiger向けではありません)。
apython312.dmgをマウントします。install.commandをダブルクリックし、インストール先を選択します。または.tar.bz2から: tar xjf apython312-3.12.11-macosx10.4-powerpc.tar.bz2 -C <展開先>
pip / HTTPS(ssl) / sqlite3 / ctypes
(ビッグエンディアンでの正常動作を確認済み) / lzma / bz2 /
zlib / readline、Flask、Django(+ SQLite)。
_tkinter(GUIライブラリは同梱していません)cryptography>=3.4、orjson、ruffなど)
— 必要な場合はcryptography<3.4にピン留めしてください。Djangoのコア機能に
cryptographyは不要です。
純Pythonのパッケージは問題なく入ります。C拡張を含むものは、このマシンにビルド環境(Tigerbrew + GCC 14)が無いとコンパイルに失敗します。純Pythonフォールバックがあるもの(markupsafe等)は入りますが、無いものは入りません。numpy /
scipy / Pillow / lxmlは標準では動かない前提でお願いします。
Tiger自体はセキュリティ更新が提供されないOSです。同梱のOpenSSLは3.5.7と新しめですが、OSを含めた全体としては脆弱です。インターネットに公開するサーバや、重要な情報を扱う用途には使わないでください。ローカル開発・学習・LAN内での利用に留めてください。
スクリプトとパッチはMITライセンス、無保証です。同梱の共有ライブラリ(OpenSSL / SQLite / libffi / readline / gdbm / xz / zlib)はTigerbrew由来で、それぞれのライセンスに従います(readlineとgdbmは GPL-3.0)。
| apython312-3.12.11-macosx10.4-powerpc.dmg |
|---|
ae2ec58f62015e1af4fe6d67bae181f9ff95c4d638f9a41a3c8a872de7e25fd9 |
| apython312-3.12.11-macosx10.4-powerpc.tar.bz2 |
9e805ab7e6d9ee65f75071bfc8526dbb3673f9c3373c94605ed2c3ad3ee572e7 |
このビルド(内部的にはapython312という名前です)は、4箇所にパッチを当てたCPython 3.12.11を、Tigerbrew由来のGCC 14ツールチェーンで、 Xcode 2.5から復元したTiger自身のヘッダに対してビルドしたものです。こう書くとあっさりしてますが、実際は「そこに辿り着くまで」がほとんどの作業でした。この実機の初期状態が想定以上に壊れていた、というのがこのページの本題です。
出来上がるインタプリタはどちらにしても本物のPowerPCバイナリです — 「ネイティブ」か「クロス」かは単にコンパイラ自体がどこで動くかの違いでしかありません。CPythonのビルドシステムはネイティブビルド前提で、Darwin/PPCは現役でメンテされてるクロスコンパイルターゲットでもないので、クロスビルドを選ぶとconfigureとずっと戦う羽目になります。ここでは全部iBook本体上で動かしていて、
SSH越しにリモート操作しつつ、実際のコンパイル作業自体はG4本体がやっています。
4つとも構図は同じで、CPython 3.12は__APPLE__ターゲットなら当然あるはずだと決め打ちで使ってるAPIが、実際にはMac OS X 10.5か10.6になってから追加されたもの、というパターンです。
pthread_threadid_np()(10.6以降)はpthread_mach_thread_np()にフォールバック。<copyfile.h>/fcopyfile()(10.5以降)は、使われてる4箇所を#if 0で無効化。Tigerはデフォルトで__DARWIN_UNIX03が無効なため、
ttyname_rが現代の形式ではなく古いchar *を返す仕様になっていて、
posixmodule.c側はそこだけ素のttyname()を使うようにしています。
_scproxyは、まっさらなTiger環境には無いSystemConfiguration/CoreServices/
CarbonCoreのヘッダを要求してくる(Xcode 2.5のSDKから復元)んですが、単純に無効化することもできません。Darwinではurllib.requestが無条件でこれをimportするので。
今回のiBookは、何年か前に部分的なシステム再インストールが行われた形跡があって、
/usr/includeの中身がたった2ファイルしか無く、/usr/libにも
crt1.oやlibSystemStubs.aなど、普通のリンクに要るファイルが軒並み欠けていました。素のgccを叩くだけでld: can't locate file for: -lcrt1.o
になり、Tigerbrew自身のソースビルドまで巻き添えで全滅してました。おまけに、Tigerbrewの配布済みビルド(bottle)は今どきのcctools/ld64でリンクされていて、Tiger標準の古い
install_name_tool(cctools-576)ではそのMach-Oヘッダすら解釈できない(malformed object (unknown load command 11))という鶏卵問題も抱えていました。新しいcctoolsを入れるには、そのcctools自身のbottleにも同じ問題がある、という状況です。
installerコマンドが、DeveloperTools.pkgの古い形式のインストールスクリプトで詰まりました("The upgrade failed")。インストーラーを使うのを諦めて、代わりに
paxでペイロードを直接展開する方式に切り替えたところ、それだけで
MacOSX10.4u.sdkと/usr/include(2→2,516ファイル)、リンク時に必要なオブジェクトファイル一式が復元され、素のgccでのリンクが再び通るようになって、
Tigerbrew自身のビルドも動き出しました。
MACOSX_DEPLOYMENT_TARGETは明示的に指定する必要がある。
未指定のままだとGCC 4.0はデフォルトでMac OS X 10.1をターゲットにしてしまい、Python C拡張(bundle形式のMach-O)のリンクに必須の-undefined dynamic_lookup
オプションを拒否します。MACOSX_DEPLOYMENT_TARGET=10.4を指定すれば問題なくリンクできます。
--force-bottleを付けないと、GCC自身でGCCをビルドしようとして死ぬ。
cctools/ld64が新しくなってbottleを正しくpourできるようになった後も、brew install gcc
にはまだ--force-bottleを明示的に付ける必要がありました。付けないとTigerbrewがソースビルドを試みて即座に停止し、「GCC 14はGCC 4.0.1ではビルドできない」というエラーになります。代わりに配布済みのtiger_altivec bottleを使ったところ、GCC 14.2.0はきれいに入り、
-std=c11 -Werrorで_Static_assert・_Generic・
<stdatomic.h>・C++17(make_unique等)が通ることと、本物の
bundle形式のリンクが通ることを確認できました。
PowerPCはビッグエンディアンで、C拡張のコード(構造体のパッキング、バッファプロトコル、生バイトを直接触るもの)の中には、それを明言せずに暗黙にリトルエンディアン前提で書かれてるものが少なくありません。ビルドの検証には、実際にctypesを往復させるテストを使っています。C側の
qsort()から、本物のPythonコールバックで要素を比較させながら
[5,3,1,4,2]をソートさせて、結果がちゃんと[1,2,3,4,5]になることを確認する、というものです。これでlibffiのクロージャ(C側からPython側へコールバックする仕組み)が、このバイトオーダーで正しく動くことまで確認できます。単にインタプリタが起動するだけでは分からない部分です。
numpy/scipy/Pillow/lxmlはまだ手を付けていません — それぞれ独自の移植作業が要る、重いC拡張です。上のまとめには載せきれなかった、いくつかの行き止まりも含めた壁ひとつひとつの記録は、GitHubの
notes/obstacles.md
にあります。
ソースコードはGitHubにあります。
不具合報告・要望は、非公開で開発者に直接届きます。個人プロジェクトのため、返信できないことがあります。