tags:

views:

62

answers:

3

In answering SO question 3500638, Ned Deily states that the Apple-supplied Pythons (2.5.4 and 2.6.5) are both built with gcc-4.2. However, all three of the python.org OS X Pythons (2.6.5, 2.7, 3.1.2) are built using gcc-4.0.

Questions

  1. Why are the python.org Pythons (2.6.5, 2.7, 3.1.2) built using gcc-4.0?
  2. What are the gotchas of using one of the python.org Pythons built with gcc-4.0?

As for the second question, I find myself issuing one or more of the following commands prior to building Python extensions:

export CC=/usr/bin/gcc-4.0
export CPP=/usr/bin/cpp-4.0
export CXX=/usr/bin/g++-4.0
+3  A: 

It may have to do with the fact that the Apple-supplied Python (2.5.1) for OS X 10.5 is built with gcc-4.0 -- after all, python.org's DMGs support both OS X 10.5 and 10.6 (not sure if they also support older versions of the OS).

Alex Martelli
+1  A: 

According to Python issue 6957:

Recent python.org installers are built using the OS X 10.4 SDK so that one installer image will work on 10.4, 10.5 and now 10.6 (in theory, 10.3.x as well).

While this answers why the python.org Pythons use gcc-4.0, I'd still be interested in knowing if there are any gotchas beyond having to set gcc-4.0 when building Python extensions.

Matthew Rankin
+2  A: 
  1. For some time now, the python.org OS X installers have been built with the requirement to provide one Python executable and shared library that will work on all recent OS X releases that support PPC and Intel processors. A separate but closely related requirement is that it must be possible for end users to be able to build and install Python packages with C or C++ extension modules. Yet another goal is to make it easy, with the help of tools like py2app, to build and package full-fledged standalone OS X applications that can work out of the box on multiple OS releases. For various reasons, gcc-4.0 on OS X is currently the one version that meets all of those requirements. But the choice of ABI deployment target, build architectures, and OS X SDKs are important issues as well. Choosing a build environment that allows Python (the traditional cPython) itself to be built on any supported platform also helps to ensure that C extension modules can be built on any of those platforms.

    The gory details: gcc-4.0 remains the most recent gcc version supplied in the last Developer Tools releases for 10.4. The 10.5 and 10.6 Developer Tools supply both 4.0 and 4.2 but 4.0 is still the default for 10.5. Thus, gcc-4.0 is the common denominator for the three most recent OS X releases. Beyond the gcc version itself, there is also the question of which ABI to build for, i.e. what OS X calls deployment target. Generally, OS X goes to some pains to ensure backwards compatibility, allowing older binaries to work on newer systems even though most are dynamically linked. So to be able to build a Python interpreter that will work on 10.4 through 10.6, you would use gcc-4.0, set MACOSX_DEPLOYMENT_TARGET to 10.4 (the minimum OS X level needed to run), use the corresponding SDK for 10.4 (it's somewhat confusingly called 10.4u, as in universal, and is an optional install for the 10.6 versions of the Xcode Developer Tools), and set the universal architectures to i386 and ppc, the only two that are fully supported at run time on all of those systems.

    The OS X installer builds cheat a little bit and go one step step further: they actually set the deployment target to 10.3 which, it turns out, results in a binary that will work with all OS X releases, from 10.6 back to OS X 10.3.9, the final 10.3 release, although not with early 10.3 releases. (Note, if you are still using 10.3.9, since gcc-4.0 is not included with the 10.3 Developer Tools, manual intervention will likely be needed to build C extension modules there, such as overriding the gcc version, and you may run into other problems. Python on 10.3.9 gets minimal testing and exposure as part of the python.org release process these days so user beware.)

  2. Gotchas: the most important should be clear from the above. When building or installing packages with extension modules, ensure that you are using a compatible GCC version, architectures, deployment target, and SDK. Fortunately, if the package uses Python's Distutils to build and install the extension module, generally all of this will be taken care of for you automatically as Distutils uses saved values based on the Python interpreter's build environment. That covers just about every Python package that comes with a setup.py install script and applies to higher-level install tools that use Distutils under the covers, things like easy_install and pip.

    An important exception: the automatic setting by Distutils of GCC to gcc-4.0 is something that was added after the release of 10.6 made it an issue so it is not done in earlier releases of 2.6 or 3.1 and not at all in 2.5. When in doubt, you can always set and export it manually as shown in your question.

    Another common gotcha when building or installing extension modules comes up when the module uses other 3rd-party libraries or binaries. Those must also be compatible. In particular, for 10.6 the system default is to build, link, and execute as Intel-64 (-arch x86_64) where possible. This can result in the problem that 3rd-party non-Python libraries you install can't be statically or dynamically linked with the Python extension module because there is no compatible common architecture (since the python.org Python includes only the 32-bit i386 and ppc archs). To get around this, you need to be careful to force the right universal architectures when building the 3rd-party libraries. How easy it is to do that varies greatly among various libraries. The plan is for the next releases of Python 2.7 and Python 3.2 to include a second 32-bit/64-bit Intel-only universal installer option built for 10.6 and above that should make life much easier on 64-bit systems. (Note, for the initial release of 2.7 there is a second 32-bit/64-bit installer except that it was built for 10.5 and above and includes 32-bit ppc as well. Unfortunately, that configuration turns out to have a number of problems, including IDLE and Tkinter not working on 10.6. I would use it only with caution.)

    For many popular Python packages with 3rd-party library dependencies (PIL and MySQLdb come to mind), there is another approach to minimizing compatibility problems and that it is to use a complete solution (Python, Python packages, and 3rd-party libraries) from one of the third-party open source package distributors for OS X, such as MacPorts, Homebrew, or Fink. There are some pitfalls getting started with each but, in the long run, their use can often save a lot of headaches.

    Obviously another gotcha would be trying to build a package that depends on a new feature or bug fix not found in Apple's gcc-4.0 releases. I am not aware of any such packages but there could be some. If so, that might be another good reason to go with another Python solution, such as building and installing Python from MacPorts.

Ned Deily