[Pythonmac-SIG] Supporting arch specific eggs with a fat Python and setuptools
Bob Ippolito
bob at redivi.com
Tue Feb 7 08:47:04 CET 2006
With the recent introduction of i386 architecture Macs, it's becoming
a necessity to support two architectures for the platform: PPC and
i386. Fortunately this is done somewhat easily using Apple's GCC 4
compiler and their linker toolchain. Ronald and I have already
basically made all of the necessary changes to Python (in a branch on
another svn server) and distutils in order to make Python compile
with multiple architectures, and to make distutils also do the right
thing.
This solution works great (in theory and limited testing) for
everyone except Mac OS X 10.3 users. We have gone out of our way to
ensure that this build of Python is compatible with Mac OS X 10.3.9
so that those users aren't totally left in the dark, but there is a
problem: the GCC 4 toolchain required to build extensions is not
available to Mac OS X 10.3 users. They simply can not build binaries
compatible with i386.. and if they could, they couldn't link it
together as a universal binary. Bummer.
The workaround for this issue is to have a way to swap out the
Makefile with a PPC-only Makefile for those users. The problem with
that is setuptools. Currently setuptools doesn't include a lot of
intelligence for choosing eggs given multiple choices. Here's a
scenario of various Python builds and the naming of eggs they produce:
Mac OS X 10.4 with current means:
pysqlite-2.0.5-py2.4-macosx-10.4-ppc.egg
Mac OS X 10.3 with current means, or with the universal build and a
swapped Makefile:
pysqlite-2.0.5-py2.4-macosx-10.3-ppc.egg
Mac OS X 10.4 with the universal build:
pysqlite-2.0.5-py2.4-macosx-10.3-fat.egg
The decision of which egg to choose is subjective, but the greatest
benefit overall is achieved by choosing the maximally compatible
version:
pysqlite-2.0.5-py2.4-macosx-10.3-fat.egg
For users of Mac OS X, here is the egg-sorting algorithm I'm
proposing. This sort must be used only with eggs that are compatible
with the current architecture -- which means either "fat" or
_macosx_arch(os.uname()[4].replace(' ', '_')). Also allowing
_macosx_arch and universally allowing fat are going to require
another patch to setuptools (that I have not yet written, because
it's not the right thing to do until egg-sorting is right).
# a and b must only differ in platform specifics!
def cmp_platform_eggs(a, b):
if a.arch == "fat" and b.arch == "fat":
pass
elif a.arch == "fat":
return 1
elif b.arch == "fat":
return -1
# lower version sorts higher
return -cmp(a.macosx_version, b.macosx_version)
This sort means that fat will always be preferred, and lower
requirements sort higher. This makes it easier for people who wish
to redistribute self-contained applications to other users (a la
py2app, py2exe, cx_Freeze), which is a very important use case for
this platform.
-bob
More information about the Pythonmac-SIG
mailing list