Building a GNU Toolchain for ARM

The following is now based on the instructions at GNU ARM to build a toolchain using GCC 4.0.2 for Linux. This is essentially the toolchain used by the Lejos NXT developers, except that g++ is not built, because it is not currently needed. Toolchains based on GCC 4.1.1 don't work for Lejos NXT at the moment. GCC 4.0.3 seems to work, but is not used much. For Binutils GNU ARM prescribes version 2.16.1, but 2.17 also worked so far.

First you need to download the sources. You need GCC, Binutils, Newlib. From GNU ARM you need t-arm-elf. You can also build GDB or Insight for debugging, but it is not strictly required.

Download binutils-2.16.1.tar.bz2 (14MB), gcc-core-4.0.2.tar.bz2 (17MB), newlib-1.14.0.tar.gz (8MB).

gcc-core only contains the C compiler, which suffices for Lejos NXT. If you want other languages you can download the sources separately or you can use the full gcc sources.

To build thing I used the following script:

#! /bin/sh

# Variables

export gcc_version=4.0.2
export binutils_version=2.16.1

export srcdir=$(pwd)
export target=arm-elf
export prefix=/usr/local/arm-elf-tools/gcc-${gcc_version}
export PATH="$prefix/bin":"$PATH"


# Unpack

tar jxf binutils-${binutils_version}.tar.bz2
tar jxf gcc-core-${gcc_version}.tar.bz2
tar zxf newlib-1.14.0.tar.gz
# tar jxf insight-6.5.tar.bz2

cp -f t-arm-elf gcc-${gcc_version}/gcc/config/arm


# Build

mkdir -p $prefix


# binutils

cd $prefix
mkdir build-binutils
cd build-binutils
${srcdir}/binutils-${binutils_version}/configure \
        --target=$target --prefix=$prefix \
        --enable-interwork --enable-multilib --with-float=soft
make all install


# gcc core

cd $prefix
mkdir build-gcc
cd build-gcc
${srcdir}/gcc-${gcc_version}/configure --target=$target --prefix=$prefix \
        --enable-interwork --enable-multilib --with-float=soft \
        --enable-languages="c" --with-newlib \
        --with-headers=${srcdir}/newlib-1.14.0/newlib/libc/include
make all-gcc install-gcc


# newlib

# newlib wants arm-elf-cc but there is only arm-elf-gcc, so we make a link
cd $prefix/bin
ln -s arm-elf-gcc arm-elf-cc

cd $prefix
mkdir build-newlib
cd build-newlib
${srcdir}/newlib-1.14.0/configure --target=$target --prefix=$prefix \
        --enable-multilib --enable-interwork --with-float=soft
make all install


# gcc rest

cd $prefix/build-gcc
make all install


# insight (gdb)

# cd $prefix
# mkdir build-insight
# cd build-insight
# ${srcdir}/insight-6.5/configure --target=$target --prefix=$prefix \
#         --with-gnu-as --with-gnu-ld \
#         --enable-interwork --enable-multilib --with-float=soft
# make all install


# gdb
#
# cd $prefix
# mkdir build-gdb
# cd build-gdb
# ${srcdir}/gdb-6.5/configure --target=$target --prefix=$prefix \
#         --with-gnu-as --with-gnu-ld \
#         --enable-multilib --enable-interwork --with-float=soft
# make all install

See also this chapter in the CrossGCC FAQ.

Update 2006-07-02: I modified the script to avoid the errors which were related to libssp and to configure arch and cpu for the AT91SAM7S256 in the NXT.

Update 2006-07-26: According to Ralph Hempel this also works under Cygwin.

Update 2006-10-28: I actually downloaded binutils in .tar.bz2 format, and we don't need a second pass of build-gcc with --disable-libssp. Thanks to Lawrie Griffiths and Jens Schicke for pointing this out. I also checked that the versions are still current.

Update 2007-01-06: The instructions now mostly follow GNU ARM, so that the toolchain is usable for Lejos NXT development.