Creating Universal Extensions for Perl, Python and Ruby

With the advent of the Intel processor to the Macintosh family, software needs to be compiled/linked to run on multiple architectures. In Mac OS X 10.4 and previous, extensions built by perl, python and ruby would only normally build for the native architecture. In Mac OS X 10.5 and later, extension are built universal by default, and this can be customized.

Contents:

Building Universal
Building Perl, Python and Ruby Extensions
Mac OS X 10.5 and later


Building Universal

Including the 64-bit architectures, there are currently 4 architectures that can be built:

Architecture Name

Description

i386

Intel (32-bit)

ppc

PowerPC (32-bit)

ppc64

PowerPC (64-bit)

x86_64

Intel (64-bit)

For example, to tell the compiler and linker to build the two 32-bit architectures (which is the customary setting), the following command-line arguments would be used:

-arch i386 -arch ppc

Building Perl, Python and Ruby Extensions

The process of building perl, python and ruby extensions is similar to that on other platforms. For perl, it looks something like:

% perl Makefile.PL
% make
% make install

For python, it looks something like:

% python setup.py install

And for ruby:

% ruby extconf.rb
% make
% make install

All of the arguments to the compiler and linker are automatically generated, and since most other operating systems don’t have the concept of multiple architectures, perl, python and ruby don’t know how to deal with them. It is possible to force additional architecture arguments to be used by the compiler and linker, but it isn’t pretty.

For perl, overriding some Makefile variable works in many cases (though is not the only way):

% perl Makefile.PL
% make PASTHRU_INC='-arch i386 -arch ppc' LD='cc -arch i386 -arch ppc'
% make install

Likewise, for python, this usually works:

% env CFLAGS='-arch i386 -arch ppc' LDFLAGS='-arch i386 -arch ppc' python setup.py install

And for ruby:

% env CFLAGS='-arch i386 -arch ppc' LDFLAGS='-arch i386 -arch ppc' ruby extconf.rb
% make
% make install

Mac OS X 10.5 and later

In Mac OS X 10.5 and later, the default for perl, python and ruby extensions is to build the two 32-bit architectures. In most cases, this is what is desired, so there will be no difference in the build procedures.

However, for those times when a different set of architectures is desired, a new environment variable can be used to change this. For example, to build a perl extension only for 32-bit PowerPC, you can use:

% env ARCHFLAGS='-arch ppc' perl Makefile.PL
% make
% make install

or for python:

% env ARCHFLAGS='-arch ppc' python setup.py install

or for ruby:

% env ARCHFLAGS='-arch ppc' ruby extconf.rb
% make
% make install

Note: The ARCHFLAGS environment variable can be used to build and install ruby gems as well.

Or, you can set the ARCHFLAGS environment variable globally, and then just run the normal build/install commands.

Note: Setting ARCHFLAGS to an empty string will build for the native 32-bit architecture.

Note: sudo will not pass the ARCHFLAGS environment variable to the new shell. So:

% env ARCHFLAGS='-arch ppc' sudo ...
(or setting ARCHFLAGS globally before running sudo), will not work, but switching the order will:

% sudo env ARCHFLAGS='-arch ppc' ...
Or the sudoers config file can be modified to pass ARCHFLAGS. Or even simpler, you can just run “sudo -s” and set the ARCHFLAGS environment variable in the new shell.

Note: For more complicated and/or non-standard extension builds, it may still be necessary to set environment variables, override Makefile variables or manually insert the architecture arguments, especially into Makefiles in subdirectories.





© 2007 Apple Inc. All Rights Reserved. (Last updated: 2007-10-31)


Did this document help you?
Yes: Tell us what works for you.
It’s good, but: Report typos, inaccuracies, and so forth.
It wasn’t helpful: Tell us what would have helped.