« Back to Applications

Python 3.12 (apython312)

PowerPC Mac (Tiger) 向け Source Available

CPython 3.12.11 with pip, built for Mac OS X 10.4 Tiger on PowerPC. Relocatable — drop it wherever you like. This is an unofficial, personal build, not affiliated with python.org. As far as could be found, no prior build combines Python 3.12 with Tiger specifically (3.10/3.11 exist for Leopard via MacPorts/Tigerbrew, but not this combination).

Download apython312.dmg
Downloads so far: 28
Last updated: 2026-08-30 (v3.12.11)
Prefer the command line? A .tar.bz2 is also available — extract with tar xjf apython312-3.12.11-macosx10.4-powerpc.tar.bz2 -C <destination>.
Note: Tiger's stock Safari/curl can't verify today's HTTPS certificates, so downloading here directly can fail. We recommend Aquafox — the PowerPC-era browser we make a Japanese language pack for — which handles modern HTTPS fine. Failing that, fetch the file on a modern machine and copy it over, or use a modern curl via Tigerbrew/MacPorts.

Requirements

  • Mac OS X 10.4.x (Tiger)
  • PowerPC G4 (AltiVec) or G5 — will not run on a G3
  • About 200 MB free disk space

Installation

  1. Download and mount apython312.dmg.
  2. Double-click install.command and choose an install location.

Or from the .tar.bz2: tar xjf apython312-3.12.11-macosx10.4-powerpc.tar.bz2 -C <destination>

What Works

pip, HTTPS/TLS (ssl), sqlite3, ctypes (verified big-endian-correct), lzma, bz2, zlib, readline, Flask, and Django (with SQLite).

What Doesn't Work

  • _tkinter — no GUI toolkit is bundled.
  • Anything requiring Rust (cryptography>=3.4, orjson, ruff, etc.) — pin cryptography<3.4 if you need it; Django's core doesn't require cryptography at all.

About packages with C extensions

Pure-Python packages install without any trouble. Packages with C extensions need a local build toolchain (Tigerbrew + GCC 14) to compile, which this machine doesn't have installed by default. Packages with a pure-Python fallback (like markupsafe) will still install; ones without one won't. Assume numpy, scipy, Pillow, and lxml don't work out of the box.

A Security Note

Tiger itself no longer receives security updates. The bundled OpenSSL (3.5.7) is current, but the OS underneath it is not — taken as a whole, this is not a hardened environment. Don't expose it to the internet or use it for anything sensitive. Local development, learning, and LAN use only.

License / Disclaimer

The scripts and patches here are MIT licensed, provided with no warranty. The bundled shared libraries (OpenSSL, SQLite, libffi, readline, gdbm, xz, zlib) come from Tigerbrew and follow their own licenses (readline and gdbm are GPL-3.0).

Checksums (SHA-256)

apython312-3.12.11-macosx10.4-powerpc.dmg
ae2ec58f62015e1af4fe6d67bae181f9ff95c4d638f9a41a3c8a872de7e25fd9
apython312-3.12.11-macosx10.4-powerpc.tar.bz2
9e805ab7e6d9ee65f75071bfc8526dbb3673f9c3373c94605ed2c3ad3ee572e7

Source, build scripts, and the full field report: GitHub. Also discussed on MacRumors.

This build (internally called apython312) is CPython 3.12.11, patched in four small places and built with a Tigerbrew-sourced GCC 14 toolchain, against Tiger's own headers restored from an Xcode 2.5 install. None of that sounds dramatic written out like that; getting there was most of the work. This machine's starting state turned out to be more broken than expected, and that's really what this page is about.

Native, not cross-compiled

The resulting interpreter is a real PowerPC binary either way — "native" vs. "cross" only describes where the compiler itself runs. CPython's build system assumes a native build, and Darwin/PPC isn't a maintained cross-compilation target, so cross-compiling would have meant fighting configure the entire way. Everything here runs directly on the iBook, driven remotely over SSH with the actual compiling happening on the G4 itself.

The four patches CPython needs for Tiger

All four are the same shape: CPython 3.12 assumes any __APPLE__ target has an API that actually only arrived in Mac OS X 10.5 or 10.6. pthread_threadid_np() (10.6+) falls back to pthread_mach_thread_np(). <copyfile.h>/fcopyfile() (10.5+) gets #if 0'd out in the four places it's used. Tiger defaults __DARWIN_UNIX03 off, which means ttyname_r has the old legacy char * signature instead of the modern one, so posixmodule.c uses plain ttyname() there instead. And _scproxy needs SystemConfiguration/CoreServices/ CarbonCore headers that a from-scratch Tiger install doesn't have (restored from the Xcode 2.5 SDK) — it can't just be disabled, since urllib.request imports it unconditionally on Darwin.

The toolchain almost didn't happen at all

This particular iBook turned out to have had a partial system reinstall at some point years ago: /usr/include had only 2 files in it, and /usr/lib was missing crt1.o, libSystemStubs.a, and other pieces every plain link needs — every bare gcc invocation failed with ld: can't locate file for: -lcrt1.o, which took Tigerbrew's own source builds down with it. On top of that, Tigerbrew's prebuilt bottles turned out to be linked with a modern cctools/ld64, and Tiger's own ancient install_name_tool (cctools-576) couldn't even parse their Mach-O headers (malformed object (unknown load command 11)) — a chicken-and-egg problem, since fixing that needs a newer cctools, whose own bottle has the identical problem.

Xcode 2.5's own installer couldn't install itself. The CLI installer command choked on DeveloperTools.pkg's old-format install scripts ("The upgrade failed"). Worked around it by extracting the payloads directly with pax instead of running the installer at all — that alone restored the MacOSX10.4u.sdk, /usr/include (2 → 2,516 files), and the missing link-time object files, which is what let a plain gcc link succeed again and got Tigerbrew's own builds moving.
MACOSX_DEPLOYMENT_TARGET has to be set explicitly. Leave it unset and GCC 4.0 defaults to targeting Mac OS X 10.1, which rejects -undefined dynamic_lookup — exactly the flag every Python C extension (a bundle-type Mach-O) needs to link. Set MACOSX_DEPLOYMENT_TARGET=10.4 and it links fine.
GCC 14 needed --force-bottle, or it tried to build itself with itself. Once cctools/ld64 were current enough for bottles to actually pour, brew install gcc still needed --force-bottle explicitly — without it, Tigerbrew tried a source build and stopped immediately, reporting that GCC 14 can't be built by GCC 4.0.1. With the prebuilt tiger_altivec bottle instead, GCC 14.2.0 came up clean: verified with -std=c11 -Werror against _Static_assert, _Generic, <stdatomic.h>, and C++17 (make_unique, etc.), plus a real bundle-type link.

Proving big-endian actually works

PowerPC is big-endian, and a lot of C-extension code (struct packing, buffer protocols, anything touching raw bytes) quietly assumes little-endian without ever saying so. The build gets verified with a real ctypes round-trip: a C qsort() call comparing elements via a genuine Python callback, sorting [5,3,1,4,2] and checking the result comes back exactly [1,2,3,4,5] — confirming libffi's closures (the mechanism that lets C code call back into Python) work correctly on this byte order, not just that the interpreter starts.

What's next

numpy/scipy/Pillow/lxml weren't attempted — heavy C extensions that would need their own porting work. The full obstacle-by-obstacle field report, including a couple of dead ends that didn't make it into the summary above, is in notes/obstacles.md on GitHub.

Full source code is on GitHub.

Feedback on this app

Rating (optional)