Mac OS X Universal Binaries

  • Revision slug: Mac_OS_X_Universal_Binaries
  • Revision title: Mac OS X Universal Binaries
  • Revision id: 94582
  • Created:
  • Creator: Markmentovai
  • Is current revision? No
  • Comment /* Prerequisites */ Add Xcode 2.4 10.2.8 SDK warning

Revision Content

NOTE: substantive changes to this page (non-editorial) should be reviewed by one of the build-config peers

It is possible to build Mozilla applications as a universal binary that runs natively on both PowerPC and Intel processors running Mac OS X. Universal binaries contain:

  • Compiled executable code for both architectures, such as:
    • the main executable (for example, firefox-bin)
    • shared libraries and binary plugins (for example, libxpcom.dylib)
  • A single copy of all other non-executable files, including:
    • Application resources (for example, browser.jar)
    • Localization packages (for example, en-US.jar)

Universal binaries of Mozilla applications can be built on both PowerPC and Intel-based Macs.

{{wiki.template(':en/Build_Documentation/TOC')}}


Prerequisites

You should be familiar with the Mac OS X build prerequisites before attempting to build a universal binary of a Mozilla product. In addition to the standard Mac prerequisites, universal builds have the following requirements:

  • Mozilla Source: The universal build system is supported on the trunk, the MOZILLA_1_8_BRANCH, and the MOZILLA_1_8_0_BRANCH as of late February 2006. There are no plans to port the system to earlier branches.
  • Operating System: Mac OS X 10.4 (“Tiger”) or later. This is a requirement to build Mozilla, not run it. Mozilla will continue to run on PowerPC processors with Mac OS X versions as early as 10.2.
  • Development Environment: Xcode Tools 2.2.1 or later. Apple provides downloadable Xcode updates.
  • libIDL and GLib. At the present time, these do not need to be installed as universal binaries. It is sufficient to install libIDL and GLib for the build system only, according to the normal build prerequisites. This is a temporary workaround that will remain in place only until universal binaries of libIDL and GLib can reasonably be built.
  • The Shared Menus Cocoa Framework is only required to build Camino. When building a universal binary of Camino, you must install a universal binary of this framework. Instructions are provided in Building a Universal SharedMenusCocoa.

You will not be able to build Mozilla as a universal binary if you have installed Xcode 2.4 due to a bug in the included 10.2.8 SDK. If you install Xcode 2.4, please see the Mac OS X build troubleshooting section for a workaround.

Configuration

This section describes how to check out the necessary files and configure Mozilla to build as a universal binary.

Preparation

A mozconfig fragment is provided in the Mozilla source tree that configures the universal build appropriately. It is located at mozilla/build/macosx/universal/mozconfig. If you are using CVS, you must check this file out before attempting to build, along with client.mk and any other mozconfig files that your build requires.

This command is sufficient to prepare for a universal binary of Firefox on the Mozilla trunk:

cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot co mozilla/client.mk mozilla/browser/config/mozconfig mozilla/build/macosx/universal/mozconfig

Your .mozconfig File

When preparing your own .mozconfig file, you must source the $topsrcdir/build/macosx/universal/mozconfig fragment. It should be sourced after any product-specific mozconfig, in case it needs to override any options.

Universal binaries must be built as objdir builds, so MOZ_OBJDIR must be set. The location of your objdir is unimportant, so long as you provide one.

Here is a sample .mozconfig suitable for building a universal binary of Firefox in a release configuration:

. $topsrcdir/browser/config/mozconfig
. $topsrcdir/build/macosx/universal/mozconfig
ac_add_options --enable-optimize=-O2
ac_add_options --disable-shared
ac_add_options --enable-static
ac_add_options --disable-tests
ac_add_app_options ppc --enable-prebinding
mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/../build

In this example, the objdir is placed adjacent to the mozilla directory, in a directory called build.

Options specified with ac_add_options are used to configure both the PowerPC and Intel builds. Options specified with ac_add_app_options will only apply to the listed processor. ppc or i386 must follow ac_add_app_options. In this sample configuration, prebinding is enabled for PowerPC only. This setting is recommended, because prebinding improves launch times on older versions of Mac OS X that are still supported by Mozilla for PowerPC. More recent versions of Mac OS X, including all of those that run on Intel processors, do not benefit from prebinding, so prebinding is not enabled for the Intel build.

About the Configuration

The universal binary configuration sets several options to tune the PowerPC and Intel builds separately. Most notably:

  • Compiler: The PowerPC build will be produced with GCC 3.3, and the Intel build will be produced with GCC 4.0. This will always happen automatically, and will completely override the system default compiler selected with gcc_select.
    • GCC 4.0 is only capable of producing executable code from C++ source that runs on Mac OS X 10.3.9 and later. Mozilla supports earlier releases of Mac OS X on PowerPC, so GCC 3.3 must be used on PowerPC.
    • GCC 4.0 is the only compiler able to build applications for Mac OS X on Intel.
  • Mac OS X SDK: The PowerPC build will be produced with the Mac OS X 10.2.8 SDK to ensure that it will run on Mac OS X releases as early as 10.2. The Intel build will be produced with the Mac OS X 10.4u (“Universal”) SDK, the only SDK that supports Intel on Mac OS X.

Building

Once the configuration is in place, building Mozilla as a universal binary is as easy as performing an ordinary build. Type:

make -w -f client.mk

The source code required for your build will be checked out and compiled. Two build passes are made: one to compile Mozilla for PowerPC, and another for Intel processors. Understandably, this process takes approximately twice as long as compiling for a single processor. After both passes are complete, the results are automatically merged into a single universal binary.

Results of a Build

Two subdirectories are created in your objdir: ppc and i386. Each of these directories contains a complete processor-specific build. The merged universal binary is placed in your objdir, at ppc/dist/universal with a symbolic link at i386/dist/universal.

Packaging

For most products, when configured as a universal binary, the packaging phase will produce a disk image containing the merged universal binary. In order to perform the packaging phase, you must keep the new objdir structure in mind. If you had used the sample .mozconfig above, you would build a universal disk image of Firefox by typing:

make -C ../build/ppc/browser/installer

The disk image will be produced in ../build/ppc/dist. You could just as easily substitute i386 for ppc, this only affects the location that the disk image is produced in.

To bypass universal packaging, and create a disk image containing the application for a single processor only, you can override the UNIVERSAL_BINARY variable, setting it to empty. This will package Firefox for Intel processors into a disk image, the result will not launch at all on PowerPC:

make -C ../build/i386/browser/installer UNIVERSAL_BINARY=

Appendices

Cross-Compilation

The universal build process is implemented as a PowerPC build followed by an Intel build. Whichever build is not native is performed as a cross-compilation. If desired, it is also possible to use Mozilla’s cross-compilation support to cross-compile on Mac OS X without doing a full universal build. The prerequisites are the same as for a universal build, but instead of configuring for a universal binary, the following settings are added to the .mozconfig:

# Use the next four lines if cross-compiling for Intel on a PowerPC:
CC="gcc-4.0 -arch i386"
CXX="g++-4.0 -arch i386"
ac_add_options --target=i386-apple-darwin8.0.0
ac_add_options --enable-macos-sdk=/Developer/SDKs/MacOSX10.4u.sdk

# Use the next four lines if cross-compiling for PowerPC on an Intel:
# CC="gcc-3.3 -arch ppc"
# CXX="g++-3.3 -arch ppc"
# ac_add_options --target=powerpc-apple-darwin8.0.0
# ac_add_options --enable-macos-sdk=/Developer/SDKs/MacOSX10.2.8.sdk

# This section remains the same for either type of cross-compilation.
HOST_CC="gcc-4.0"
HOST_CXX="g++-4.0"
RANLIB=ranlib
AR=ar
AS=$CC
LD=ld
STRIP="strip -x -S"
CROSS_COMPILE=1

Building a Universal SharedMenusCocoa

Camino imposes an additional requirement that the Shared Menus Cocoa framework be present. The binary that ships with this framework is PowerPC-only, and will cause Intel builds (including universal binary builds) to fail. The Shared Menus Cocoa framework package contains source code. This section describes how to build a universal binary of the framework from that source.

  • Download SharedMenusCocoa, mount the disk image, and copy the SharedMenusCocoa folder to your hard drive. You can now eject and discard the disk image.
  • Open the SharedMenusCocoa folder, and double-click the SharedMenusCocoa.pbproj project inside. This will launch Xcode.
  • In the dialog that appears, click “Upgrade a Copy” to upgrade the project file to the Xcode 2.1 format. Name your upgraded copy SharedMenusCocoa.xcodeproj.
  • From the “Project” menu, select “Upgrade All Targets in Project to Native”, and click “Upgrade” in the sheet that appears.
  • A “Native Target Upgrade Log” window will appear. It may be closed.
  • From the “Project” menu, select “Edit Project Settings”, and select the “Build” tab in the settings window.
  • Set “Architectures” to ppc i386 by double-clicking Architectures, typing “ppc i386”, and pressing return.
  • Add the following four new settings. Settings are added by clicking the “+” button below the settings list. You should add these settings:
    • GCC_VERSION_i386 = 4.0
    • GCC_VERSION_ppc = 3.3
    • SDKROOT_i386 = /Developer/SDKs/MacOSX10.4u.sdk
    • SDKROOT_ppc = /Developer/SDKs/MacOSX10.2.8.sdk
  • Close the settings window.
  • From the “Project” menu, choose “Set Active Build Configuration”, and set it to “Default”.
  • Click “Build” in the project window’s toolbar, and wait for the build process to complete. It should complete successfully with no errors, although some warnings may be produced.
  • You now have a universal binary of SharedMenusCocoa. Quit Xcode.
  • Copy SharedMenusCocoa.framework from build/Default/SharedMenusCocoa.framework to /Library/Frameworks.

Don’t forget to provide symbolic links to the framework from the SDKs. From a shell, type:

sudo mkdir -p /Developer/SDKs/MacOSX10.2.8.sdk/Library/Frameworks
sudo ln -s /Library/Frameworks/SharedMenusCocoa.framework /Developer/SDKs/MacOSX10.2.8.sdk/Library/Frameworks
sudo mkdir -p /Developer/SDKs/MacOSX10.4u.sdk/Library/Frameworks
sudo ln -s /Library/Frameworks/SharedMenusCocoa.framework /Developer/SDKs/MacOSX10.4u.sdk/Library/Frameworks

Additional information is available in the Camino build instructions.

Revision Source

<p>
<span class="comment">NOTE: substantive changes to this page (non-editorial)      should be reviewed by one of the build-config peers</span>
</p><p>It is possible to build Mozilla applications as a <a class="external" href="http://developer.apple.com/transition/">universal binary</a> that runs natively on both PowerPC and Intel processors running Mac OS X.  Universal binaries contain:
</p>
<ul><li> Compiled executable code for both architectures, such as:
<ul><li> the main executable (for example, <code>firefox-bin</code>)
</li><li> shared libraries and binary plugins (for example, <code>libxpcom.dylib</code>)
</li></ul>
</li><li> A single copy of all other non-executable files, including:
<ul><li> Application resources (for example, <code>browser.jar</code>)
</li><li> Localization packages (for example, <code>en-US.jar</code>)
</li></ul>
</li></ul>
<p>Universal binaries of Mozilla applications can be built on both PowerPC and Intel-based Macs.
</p><p>{{wiki.template(':en/Build_Documentation/TOC')}}
</p><p><br>
</p>
<h3 name="Prerequisites"> Prerequisites </h3>
<p>You should be familiar with the <a href="en/Mac_OS_X_Build_Prerequisites">Mac OS X build prerequisites</a> before attempting to build a universal binary of a Mozilla product.  In addition to the standard Mac prerequisites, universal builds have the following requirements:
</p>
<ul><li> <b>Mozilla Source:</b> The universal build system is supported on the trunk, the <code>MOZILLA_1_8_BRANCH</code>, and the <code>MOZILLA_1_8_0_BRANCH</code> as of late February 2006.  There are no plans to port the system to earlier branches.
</li><li> <b>Operating System:</b> Mac OS X 10.4 (“Tiger”) or later.  This is a requirement to build Mozilla, not run it.  Mozilla will continue to run on PowerPC processors with Mac OS X versions as early as 10.2.
</li><li> <b>Development Environment:</b> <a class="external" href="http://developer.apple.com/tools/xcode/">Xcode Tools</a> 2.2.1 or later.  Apple provides downloadable <a class="external" href="http://developer.apple.com/tools/download/">Xcode updates.</a>
</li><li> <b><a class="external" href="http://andrewtv.org/libIDL/">libIDL</a></b> and <b><a class="external" href="http://www.gtk.org/">GLib.</a></b>  At the present time, these do not need to be installed as universal binaries.  It is sufficient to install libIDL and GLib for the build system only, according to the normal <a href="en/Mac_OS_X_Build_Prerequisites#Software_Requirements">build prerequisites</a>.  This is a temporary workaround that will remain in place only until universal binaries of libIDL and GLib can reasonably be built.
</li><li> The <b>Shared Menus Cocoa Framework</b> is only required to build <a class="external" href="http://www.caminobrowser.org/">Camino.</a>  When building a universal binary of Camino, you must install a universal binary of this framework.  Instructions are provided in <a href="#Building_a_Universal_SharedMenusCocoa">Building a Universal SharedMenusCocoa</a>.
</li></ul>
<p><b>You will not be able to build Mozilla as a universal binary if you have installed Xcode 2.4 due to a bug in the included 10.2.8 SDK.  If you install Xcode 2.4, please see the <a href="en/Mac_OS_X_Build_Prerequisites#Troubleshooting">Mac OS X build troubleshooting</a> section for a workaround.</b>
</p>
<h3 name="Configuration"> Configuration </h3>
<p>This section describes how to check out the necessary files and configure Mozilla to build as a universal binary.
</p>
<h4 name="Preparation"> Preparation </h4>
<p>A <code>mozconfig</code> fragment is provided in the Mozilla source tree that configures the universal build appropriately.  It is located at <code>mozilla/build/macosx/universal/mozconfig</code>.  If you are using <a href="en/Mozilla_Source_Code_Via_CVS">CVS</a>, you must check this file out before attempting to build, along with <code>client.mk</code> and any other <code>mozconfig</code> files that your build requires.
</p><p>This command is sufficient to prepare for a universal binary of Firefox on the Mozilla trunk:
</p>
<pre class="eval">cvs -d :pserver:anonymous@cvs-mirror.mozilla.org:/cvsroot co mozilla/client.mk mozilla/browser/config/mozconfig mozilla/build/macosx/universal/mozconfig
</pre>
<h4 name="Your_.mozconfig_File"> Your .mozconfig File </h4>
<p>When preparing your own <code><a href="en/Configuring_Build_Options">.mozconfig</a></code> file, you must source the <code>$topsrcdir/build/macosx/universal/mozconfig</code> fragment.  It should be sourced after any product-specific <code>mozconfig</code>, in case it needs to override any options.
</p><p>Universal binaries must be built as <a href="en/Configuring_Build_Options#Building_with_an_Objdir">objdir builds</a>, so <code>MOZ_OBJDIR</code> must be set.  The location of your objdir is unimportant, so long as you provide one.
</p><p>Here is a sample <code>.mozconfig</code> suitable for building a universal binary of Firefox in a release configuration:
</p>
<pre class="eval">. $topsrcdir/browser/config/mozconfig
. $topsrcdir/build/macosx/universal/mozconfig
ac_add_options --enable-optimize=-O2
ac_add_options --disable-shared
ac_add_options --enable-static
ac_add_options --disable-tests
ac_add_app_options ppc --enable-prebinding
mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/../build
</pre>
<p>In this example, the objdir is placed adjacent to the <code>mozilla</code> directory, in a directory called <code>build</code>.
</p><p>Options specified with <code>ac_add_options</code> are used to configure both the PowerPC and Intel builds.  Options specified with <code>ac_add_app_options</code> will only apply to the listed processor.  <code>ppc</code> or <code>i386</code> must follow <code>ac_add_app_options</code>.  In this sample configuration, prebinding is enabled for PowerPC only.  This setting is recommended, because prebinding improves launch times on older versions of Mac OS X that are still supported by Mozilla for PowerPC.  More recent versions of Mac OS X, including all of those that run on Intel processors, do not benefit from prebinding, so prebinding is not enabled for the Intel build.
</p>
<h4 name="About_the_Configuration"> About the Configuration </h4>
<p>The universal binary configuration sets several options to tune the PowerPC and Intel builds separately.  Most notably:
</p>
<ul><li> <b>Compiler:</b> The PowerPC build will be produced with GCC 3.3, and the Intel build will be produced with GCC 4.0.  This will always happen automatically, and will completely override the system default compiler selected with <code>gcc_select</code>.
<ul><li> GCC 4.0 is only capable of producing executable code from C++ source that runs on Mac OS X 10.3.9 and later.  Mozilla supports earlier releases of Mac OS X on PowerPC, so GCC 3.3 must be used on PowerPC.
</li><li> GCC 4.0 is the only compiler able to build applications for Mac OS X on Intel.
</li></ul>
</li><li> <b>Mac OS X SDK:</b> The PowerPC build will be produced with the Mac OS X 10.2.8 SDK to ensure that it will run on Mac OS X releases as early as 10.2.  The Intel build will be produced with the Mac OS X 10.4u (“Universal”) SDK, the only SDK that supports Intel on Mac OS X.
</li></ul>
<h3 name="Building"> Building </h3>
<p>Once the configuration is in place, building Mozilla as a universal binary is as easy as performing an ordinary build.  Type:
</p>
<pre class="eval">make -w -f client.mk
</pre>
<p>The source code required for your build will be checked out and compiled.  Two build passes are made: one to compile Mozilla for PowerPC, and another for Intel processors.  Understandably, this process takes approximately twice as long as compiling for a single processor.  After both passes are complete, the results are automatically merged into a single universal binary.
</p>
<h4 name="Results_of_a_Build"> Results of a Build </h4>
<p>Two subdirectories are created in your objdir: <code>ppc</code> and <code>i386</code>.  Each of these directories contains a complete processor-specific build.  The merged universal binary is placed in your objdir, at <code>ppc/dist/universal</code> with a symbolic link at <code>i386/dist/universal</code>.
</p>
<h4 name="Packaging"> Packaging </h4>
<p>For most products, when configured as a universal binary, the packaging phase will produce a disk image containing the merged universal binary.  In order to perform the packaging phase, you must keep the new objdir structure in mind.  If you had used the <a href="#Your_.mozconfig_File">sample <code>.mozconfig</code></a> above, you would build a universal disk image of Firefox by typing:
</p>
<pre class="eval">make -C ../build/ppc/browser/installer
</pre>
<p>The disk image will be produced in <code>../build/ppc/dist</code>.  You could just as easily substitute <code>i386</code> for <code>ppc</code>, this only affects the location that the disk image is produced in.
</p><p>To bypass universal packaging, and create a disk image containing the application for a single processor only, you can override the <code>UNIVERSAL_BINARY</code> variable, setting it to empty.  This will package Firefox for Intel processors into a disk image, the result will not launch at all on PowerPC:
</p>
<pre class="eval">make -C ../build/i386/browser/installer UNIVERSAL_BINARY=
</pre>
<h3 name="Appendices"> Appendices </h3>
<h4 name="Cross-Compilation"> Cross-Compilation </h4>
<p>The universal build process is implemented as a PowerPC build followed by an Intel build.  Whichever build is not native is performed as a cross-compilation.  If desired, it is also possible to use <a class="external" href="http://www.mozilla.org/build/cross-compiling.html">Mozilla’s cross-compilation support</a> to cross-compile on Mac OS X without doing a full universal build.  The <a href="#Prerequisites">prerequisites</a> are the same as for a universal build, but instead of configuring for a universal binary, the following settings are added to the <code>.mozconfig</code>:
</p>
<pre class="eval"># Use the next four lines if cross-compiling for Intel on a PowerPC:
CC="gcc-4.0 -arch i386"
CXX="g++-4.0 -arch i386"
ac_add_options --target=i386-apple-darwin8.0.0
ac_add_options --enable-macos-sdk=/Developer/SDKs/MacOSX10.4u.sdk

# Use the next four lines if cross-compiling for PowerPC on an Intel:
# CC="gcc-3.3 -arch ppc"
# CXX="g++-3.3 -arch ppc"
# ac_add_options --target=powerpc-apple-darwin8.0.0
# ac_add_options --enable-macos-sdk=/Developer/SDKs/MacOSX10.2.8.sdk

# This section remains the same for either type of cross-compilation.
HOST_CC="gcc-4.0"
HOST_CXX="g++-4.0"
RANLIB=ranlib
AR=ar
AS=$CC
LD=ld
STRIP="strip -x -S"
CROSS_COMPILE=1
</pre>
<h4 name="Building_a_Universal_SharedMenusCocoa"> Building a Universal SharedMenusCocoa </h4>
<p><a class="external" href="http://www.caminobrowser.org/">Camino</a> imposes an additional requirement that the Shared Menus Cocoa framework be present.  The binary that ships with this framework is PowerPC-only, and will cause Intel builds (including universal binary builds) to fail.  The Shared Menus Cocoa framework package contains source code.  This section describes how to build a universal binary of the framework from that source.
</p>
<ul><li> <a class="external" href="ftp://ftp.url-manager.com/pub/SharedMenusCocoa.dmg.bin">Download</a> SharedMenusCocoa, mount the disk image, and copy the <code>SharedMenusCocoa</code> folder to your hard drive.  You can now eject and discard the disk image.
</li><li> Open the <code>SharedMenusCocoa</code> folder, and double-click the <code>SharedMenusCocoa.pbproj</code> project inside.  This will launch Xcode.
</li><li> In the dialog that appears, click “Upgrade a Copy” to upgrade the project file to the Xcode 2.1 format.  Name your upgraded copy <code>SharedMenusCocoa.xcodeproj</code>.
</li><li> From the “Project” menu, select “Upgrade All Targets in Project to Native”, and click “Upgrade” in the sheet that appears.
</li><li> A “Native Target Upgrade Log” window will appear.  It may be closed.
</li><li> From the “Project” menu, select “Edit Project Settings”, and select the “Build” tab in the settings window.
</li><li> Set “Architectures” to <code>ppc i386</code> by double-clicking Architectures, typing “ppc i386”, and pressing return.
</li><li> Add the following four new settings.  Settings are added by clicking the “+” button below the settings list.  You should add these settings:
<ul><li> <code>GCC_VERSION_i386 = 4.0</code>
</li><li> <code>GCC_VERSION_ppc = 3.3</code>
</li><li> <code>SDKROOT_i386 = /Developer/SDKs/MacOSX10.4u.sdk</code>
</li><li> <code>SDKROOT_ppc = /Developer/SDKs/MacOSX10.2.8.sdk</code>
</li></ul>
</li><li> Close the settings window.
</li><li> From the “Project” menu, choose “Set Active Build Configuration”, and set it to “Default”.
</li><li> Click “Build” in the project window’s toolbar, and wait for the build process to complete.  It should complete successfully with no errors, although some warnings may be produced.
</li><li> You now have a universal binary of SharedMenusCocoa.  Quit Xcode.
</li><li> Copy <code>SharedMenusCocoa.framework</code> from <code>build/Default/SharedMenusCocoa.framework</code> to <code>/Library/Frameworks</code>.
</li></ul>
<p>Don’t forget to provide symbolic links to the framework from the SDKs.  From a shell, type:
</p>
<pre class="eval">sudo mkdir -p /Developer/SDKs/MacOSX10.2.8.sdk/Library/Frameworks
sudo ln -s /Library/Frameworks/SharedMenusCocoa.framework /Developer/SDKs/MacOSX10.2.8.sdk/Library/Frameworks
sudo mkdir -p /Developer/SDKs/MacOSX10.4u.sdk/Library/Frameworks
sudo ln -s /Library/Frameworks/SharedMenusCocoa.framework /Developer/SDKs/MacOSX10.4u.sdk/Library/Frameworks
</pre>
<p>Additional information is available in the <a class="external" href="http://www.caminobrowser.org/development/build/">Camino build instructions.</a>
</p>
Revert to this revision