Building an ARM cross toolchain with crosstool

Introduction

The goal of this tutorial is to guide you through the process of using crosstool to build an ARM cross toolchain. This toolchain will only include the C and C++ languages, but might contain many others (Java, Objective C, fortran or ada). And it will be built upon the last 4.1.x gnu compiler available release.

The compilation process will take place on a GNU/Linux distribution. However, it is even possible to repeat this process in different operating systems such as NetBSD, Mac OSX, Cygwin, Solaris. And for many different platforms such as mips, sh3, sh4, cris, powerpc, etc.

If you are interested in learning all the sub-utilities of the crosstool scripts you may look at the internal crosstool-howto located at: http://www.kegel.com/crosstool/current/doc/crosstool-howto.html.

To find out more about crosstool and its capabilities see the project's website's: http://www.kegel.com/crosstool/

Prerequisite

The latest available release by the time this tutorial was written is 0.43.
Downloading the crosstool-0.43 can be done at http://www.kegel.com/crosstool/crosstool-0.43.tar.gz.

In order to conveniently use crosstool, the following recommendations should be applied:

  • it is strictly forbidden to proceed as root
  • the user you are logged through should have complete access to the place crosstool is untared.

For examples:

  • In Ubuntu, it is advised to untar crosstool on a place inside your home directory.
  • In Fedora Core, log as a normal user (not root) and su in your terminal before using the crosstool scripts.

Finally, get crosstool and untar it by typing the following commands:

wget http://www.kegel.com/crosstool/crosstool-0.43.tar.gz
tar -xvzf crosstool-0.43.tar.gz

File organization

Generalities

Once you untar crosstool, you will notice a great number of script files.
Among all these files, the entry points that will allow us to reach the final result are the ones prefixed by demo-.
It is enough to execute one of these demo-xxx.sh scripts in order to get (after a few hours and gigabytes of downloads and compilations) the expected result.

As you can see, there are many of these demo-xxx.sh scripts, that gives you an idea of the number of supported platforms.

  • Alpha
  • Many of the arm variants
  • i686 and ia64
  • Motorola m68k
  • Mips and Mipsel
  • Sh3 and Sh4
  • Sparc and Sparc64
  • x86_64

Once you are interested in compiling a specific release of the GNU toolchain on a specific platform, it is highly recommended to look at the build matrix of the crosstool project http://www.kegel.com/crosstool/crosstool-0.43/buildlogs in order to check if the compilation is feasible.
Although, this build matrix is not updated with the latest available GNU toolchain. Nevertheless, it gives a good indication of what can be done.

If you have succeeded in the compilation of a toolchain that is not already indicated in the build matrix, you are welcome to update Dan Kegel with your results.

the demo-xxx.sh script

As I said before, compiling a toolchain consists in executing one of these scripts. This is what you will see if you plan to open one of these files:

#!/bin/sh
# This script has one line for each known working toolchain
# for this architecture.  Uncomment the one you want.
# Generated by generate-demo.pl from buildlogs/all.dats.txt

set -ex
TARBALLS_DIR=$HOME/downloads
RESULT_TOP=/opt/crosstool
export TARBALLS_DIR RESULT_TOP
GCC_LANGUAGES="c,c++"
export GCC_LANGUAGES

# Really, you should do the mkdir before running this,
# and chown /opt/crosstool to yourself so you don't need to run as root.
mkdir -p $RESULT_TOP

eval `cat xxx.dat gcc-4.1.0-glibc-2.3.2-tls.dat` sh all.sh --notest

echo Done.

TARBALLS_DIR is the location where the downloaded files will be saved to.
RESULT_TOP is the location the compiled toolchain will be installed to.
GCC_LANGUAGES represents the list of the languages your toolchain will support (c, c++, java, fortran, ada or objective-c).

The xxx.dat file indicates:

  • The option to pass to the kernel through the xxx.config file.
  • The name of the resulting toolchain, for example arm-unknown-linux-gnu.
  • Some specific compilation flags.

The releases of the different components compiled to provide the toolchain are indicated under such a gcc-4.1.0-glibc-2.3.2.dat file. These files are indexed according to the GCC/GLIBC versions.

These components include:

  • binutils
  • gcc core
  • gcc
  • glibc
  • kernel
  • libc headers
  • gdb

A sample content of such a file:

   BINUTILS_DIR=binutils-2.16.1
   GCC_CORE_DIR=gcc-3.3.6
   GCC_DIR=gcc-4.1.0
   GLIBC_DIR=glibc-2.3.2
   LINUX_DIR=linux-2.6.15.4
   LINUX_SANITIZED_HEADER_DIR=linux-libc-headers-2.6.12.0
   GLIBCTHREADS_FILENAME=glibc-linuxthreads-2.3.2
   GDB_DIR=gdb-6.5

The script all.sh is in charge of downloading the files quoted in the previous detailed dat file, applying (if needed) patches to the different components, compiling them and installing the requested toolchain in the installation directory.

Compiling an ARM toolchain

The following example will show you how to compile an ARM cross toolchain supporting the c, c++ and java languages, and based on gnu gcc 4.1.3.

Consulting the build matrix, I can see an ARM toolchain has been successfully compiled with the following components:

  • gcc 4.1.1
  • core gcc 3.3.6
  • glibc 2.3.2
  • binutils 2.16.1
  • kernel 2.6.15.4
  • headers 2.6.12.0

Then I have reason to suppose it will also succeed with gcc 4.1.3. I created the file gcc-4.1.3-glibc-2.3.2.dat, copied the content of gcc-4.1.0.glibc-2.3.2.dat and changed GCC_DIR from gcc-4.1.0 to gcc-4.1.3.

The content of the updated dem-arm.sh to support the new requested toolchain becomes:

  
#!/bin/sh
# This script has one line for each known working toolchain
# for this architecture.  Uncomment the one you want.
# Generated by generate-demo.pl from buildlogs/all.dats.txt

set -ex
TARBALLS_DIR=$HOME/downloads
RESULT_TOP=$HOME/crosstool
export TARBALLS_DIR RESULT_TOP
GCC_LANGUAGES="c,c++,java"
export GCC_LANGUAGES

# Really, you should do the mkdir before running this,
# and chown /opt/crosstool to yourself so you don't need to run as root.
mkdir -p $RESULT_TOP

eval `cat arm.dat gcc-4.1.3-glibc-2.3.2.dat` sh all.sh --notest

echo Done.
Executing ./demo-arm.sh should produce the expected result under $HOME/crosstool.
Written by David Sayada.

Edit History Last Modified March 10, 2008