You are here: Minimo project page > Cross-Compiling Minimo
This is a history lesson. Please use OpenEmbedded or a scratchbox!
Cross-Compiling Minimo
This is a step-by-step guide explaining how to cross-compile Minimo for ARM-Linux. We cover setup of the GCC toolchain and use that toolchain to cross-compile XFree86 and GTK+2 in preparation for cross-compiling Minimo. We use a x86-Linux host platform. Finally, we show how to write a mozconfig file for use with the toolchain.
- Building the GCC Toolchain
- Building XFree86
- Building pkgconfig
- Building GTK+-2, et al
- Building libIDL-2
- Building Minimo
Building the GCC Toolchain
Many GCC toolchains are available for the ARM-Linux platform, so the natural question is why bother creating one if so many are already available? Well, the answer is simply that we wanted to be able to update the toolchain to the latest version of GCC ourselves. This proved important as we found older versions of GCC to contain code generation bugs for target ARM that caused our Minimo builds to crash. Being able to easily upgrade components of the toolchain proved quite invaluable ;-)
Download the Source
We used the following packages from the GNU project:
We also downloaded the Linux headers for our target device. You should be sure to get headers that match the exact version of the kernel you will be using. In our case, we are using a pre-release version of Familiar Linux v0.7 with Linux kernel version:
linux-2.4.19-rmk6-pxa1-hh11
See familiar.handhelds.org for more information on Familiar Linux. We recommend using the latest stable version of Familiar Linux. Kernel headers are usually available with the distribution. For example, if you are using Familiar Linux v0.7.1 (which is the latest stable release at the time of this writing), then you will want to download the following tarball:
Of course, this may vary depending on your particular device and Linux distribution.
Download all of these packages into the following directory:
/opt/toolchain/src
The only thing special about this directory is that we will be referring to it later on. Also, the build scripts we provide will need to be modified if you decide to change this directory location.
Manually unpack the kernel headers like so:
$ tar xfz kernel-headers-ipaqpxa-2.4.19-rmk6-pxa1-hh13.tar.gz$ mkdir linux$ mv include linux
Patches and the Build Script
Unfortunately, the GNU packages do not build for target ARM cleanly without some minor modifications. You'll need the following patches for GCC and GLIBC:
Download and place these in the directory next to the GNU packages. Next, download our build script and place it in the same directory.
Build It
Now you are ready to build the GCC toolchain. It has been reported that this build script does not work when run as root. Verify that you have a few gigabytes handy, and simply execute build.sh, like so:
$ chmod +x build.sh$ ./build.sh
The build script will list the build steps it is going to perform and will prompt
you to begin the build process. If a problem occurs and you need to re-build a
particular package, you can do so by editing build.sh, and uncommenting the
appropriate export SKIP_XXX lines. For example, to
begin from GLIBC without recompiling GDB, Binutils, and GCC (first pass), you
should edit the top of build.sh to look like:
export SKIP_GDB=1export SKIP_BINUTILS=1export SKIP_GCC1=1#export SKIP_GLIBC=1#export SKIP_GCC2=1
This is very handy when you need to tweak one of the packages (which hopefully you'll be lucky enough to avoid).
Verification
When the build completes, the next step is to verify that the toolchain works. The following C program is an excellent test case since it also verifies that the system header files were detected and installed correctly. (Mozilla expects limits.h to define PATH_MAX, and it will do so if GCC is built correctly.)
#include <stdio.h>
#include <limits.h>
int main()
{
printf("PATH_MAX=%u\n", PATH_MAX);
return 0;
}
To compile this program, run the following command (assuming the source file is
saved as test.c):
$ /opt/toolchain/bin/arm-linux-gcc test.c -o test
If you get no errors, then you are well on your way to having a working toolchain. You should try running this program on your device to ensure that it works as expected. You may also want to take this moment to try out some sample C and C++ test cases of your own to verify that the toolchain is working.
Building XFree86
Download the Source
You only need to download the first 3 packages from the XFree86 distribution. We used the following packages:
Download these packages into a temporary directory. This doesn't need to be any location in particular.
Build Steps
Cross-compiling XFree86 is a little bit involved. The default packages are
already setup to handle cross-compiling without much hacking, but we found that
some tweaking was required. We had to modify our toolchain slightly to
get XFree86 to compile. XFree86 expects to find cc
and cpp in
/opt/toolchain/arm-linux/bin. In our toolchain
those executables do not exist, so we had to set the following symlinks:
$ ln -s /opt/toolchain/bin/arm-linux-cpp /opt/toolchain/arm-linux/bin/cpp$ ln -s /opt/toolchain/bin/arm-linux-gcc /opt/toolchain/arm-linux/bin/cc
Unpack the source files with the following commands:
gzip -d < X430src-1.tgz | tar xf -gzip -d < X430src-2.tgz | tar xf -gzip -d < X430src-3.tgz | tar xf -
You should see a directory named xc.
Next, run the following commands:
$ mkdir build$ (cd build && lndir ../xc)
This generates the build directory. Finally,
we need to tell the XFree86 build system to not compile the font packages
(because we didn't download them). Run the following command to disable
building fonts:
$ echo '#define BuildFonts NO' > build/config/cf/host.def
Now you are ready to build XFree86, which is done with the following command:
$ (cd build && make World CROSSCOMPILEDIR=/opt/toolchain/arm-linux/bin)
Installation
All we really need from our XFree86 build are the lib and
include directories and the
freetype-config script.
By default, XFree86 installation will install more than just these components,
and it will add extra levels of directory hierarchy that we do not need.
A simple way to deal with this is to let it install everything into a temporary
directory. Then, we can manually copy the directories that we care about.
Run this command to install everything under a temporary directory:
$ (cd build && make install DESTDIR=/tmp/xfree86/dist)
In our case, the install fails while installing programs/xterm. This is okay
since it has already installed the necessary libraries and header files.
At this point under /tmp/xfree86/dist/usr/X11R6,
you should see bin,
include, and lib
directories. We moved these second two directories into our toolchain under
/opt/toolchain/arm-linux/local/X11R6 like so:
$ mkdir -p /opt/toolchain/arm-linux/local/X11R6$ cd /tmp/xfree86/dist/usr/X11R6$ mv include /opt/toolchain/arm-linux/local/X11R6$ mv lib /opt/toolchain/arm-linux/local/X11R6
The only executable that we care about is freetype-config.
We put this into /opt/toolchain/arm-linux/local/bin
since that is where other configuration scripts will live when we are done
building the toolchain. The XFree86 build process unfortunately encodes absolute
paths into this file. Not knowing enough about how to configure XFree86 properly,
we needed to manually fix-up this file after installation. You can download this
freetype-config.diff patch to
apply our changes to the generated file.
$ mkdir -p /opt/toolchain/arm-linux/local/bin$ cd /opt/toolchain/arm-linux/local/bin$ cp /tmp/xfree86/dist/usr/X11R6/bin/freetype-config$ patch -p0 < /path/to/freetype-config.diff
In addition, the XFree86 installation included a few .pc files meant
to be used with the pkgconfig utility. Our toolchain does
not yet have this utility, but we will add it shortly. To complete the
XFree86 toolchain, we need to manually fix-up the generated .pc
files. Like freetype-config, these files have absolute paths
encoded in them. You can download this
xfree86-pc.diff patch to apply our
changes to the generated .pc files.
$ cd /opt/toolchain/arm-linux/local/X11R6/lib/pkgconfig$ patch -p0 < /path/to/xfree86-pc.diff
Finally, the libtool program used by
Pango (at least) requires that there exist .la files for
libfreetype and libexpat.
Unfortunately, the XFree86 installation does not create these files. We've
found these files in our host system and modified them by hand to make them
work with the toolchain. You can
download libfreetype.la and
download libexpat.la.
These files need to be copied into
/opt/toolchain/arm-linux/local/X11R6/lib
alongside their .so counterparts.
Building pkgconfig
To build GTK+-2 (and friends) as well as libIDL-2, we first need to have a working installation of pkgconfig in our toolchain.
Download the Source
We are using the latest release of pkgconfig, which is as of this writing version 0.15. It can be downloaded from here:
Build Steps
Download our build script
to simplify building and installing pkgconfig. Put
build-pkgconfig.sh and the
downloaded pkgconfig-0.15.tar.gz in a
temporary directory next to one another, and run these commands:
$ chmod +x build-pkgconfig.sh$ ./build-pkgconfig.sh
Assuming the command completes without any errors, verify that
/opt/toolchain/arm-linux/local/bin/pkg-config
exists. At this point, there aren't any installed packages that
pkgconfig can access. We need to
manually add the .pc files from the XFree86 installation,
so that pkgconfig can see those files.
Here's the commands that need to be run:
$ mkdir -p /opt/toolchain/arm-linux/local/lib/pkgconfig$ cd /opt/toolchain/arm-linux/local/lib/pkgconfig$ ln -s ../../X11R6/lib/pkgconfig/fontconfig.pc$ ln -s ../../X11R6/lib/pkgconfig/xft.pc$ ln -s ../../X11R6/lib/pkgconfig/xcursor.pc
Now if you run the command
/opt/toolchain/arm-linux/local/bin/pkg-config --list-all
you should see the following output:
fontconfig Fontconfig - Font configuration and customization library xcursor Xcursor - X Cursor library xft Xft - X FreeType library
Building GTK+2, et al
This step is mostly automated with a build script.
Download the Source
We are using the following packages:
Requirements
You will need an installation of glib-2 on the host machine. In particular, you will need the GLIB executables glib-genmarshal, glib-mkenums, etc. If you do not have these installed on your host machine, then you should do so now.
Build Steps
Next, download the following files:
Put these files next to the downloaded source packages, and run these commands:
$ chmod +x build-gtk2.sh$ ./build-gtk2.sh
It will compile and install all of the packages.
To verify that GTK+ is properly compiled, it is a good idea to try building some of the test programs that are included with the GTK+ package. Make sure these run okay on your device before attempting to build Mozilla!
Building libIDL-2
The Minimo build requires a version of libIDL that is compiled for
the target machine. Though Minimo itself does not use this library, it is
needed to build xpidl for the target machine.
It is probably possible to modify the Mozilla build process to skip building
xpidl to avoid this dependency.
Download the Source
We are using the following package:
Build Steps
Next, download the following files:
Put these files next to the downloaded source package, and run
build-libIDL.sh. It will compile and install
libIDL.
Building Minimo
Now, you are ready to build Minimo for target ARM.
Download the Source
Download the Mozilla source code by following the download source code instructions.
Download required patches
As of the time of this writing, you will need to apply patches to the Mozilla source tree to build the crypto module. If you do not want to build the crypto module, then you can skip this step. Otherwise, please download the latest patches from bug 209814 and bug 172651 and apply those to your tree. Once those bugs are fixed, you can obviously skip this step.
Build Steps
Download our mozconfig file for cross-compiling Minimo for target ARM, and set the following environment variables:
$ export MOZ_OBJDIR=/path/to/minimo-cc-opt-build$ export MOZCONFIG=/path/to/minimo-cc-opt.mozconfig
You can skip setting MOZ_OBJDIR if you prefer, but we recommend setting this variable to avoid cluttering the source tree with output files from the Mozilla build.
Next, start the build:
$ cd /path/to/mozilla$ gmake -f client.mk build
Once this build completes, you should be able to run the executable
$MOZ_OBJDIR/dist/bin/TestGtkEmbed on the
iPAQ. Copy all of the files from the bin
directory onto the device, or mount the directory containing these files
via NFS (which works quite well for testing purposes). Note that this is
not yet a complete Minimo build.
To complete the Minimo build, you need to run the packaging script. The packaging script performs the following steps:
- It eliminates some unnecessary components that reside in
dist/binafter the Minimo build completes, - Links all .xpt files into one single file, and
- Flattens the chrome files and installs a simpler chrome registry implementation.
To run the packager script, type the following commands:
cd $MOZ_OBJDIR/embedding/minimomakecd /path/to/mozilla/embedding/minimo./package.sh
When these commands complete, you should find a stripped down version
of Minimo in $MOZ_OBJDIR/dist/Embed. Again,
the executable name is TestGtkEmbed.