Installing a Cross Compiler

This document will help you obtain Debian packages of a cross-compilation toolchain. It is based on a HOWTO by Josh Triplett, with his kind permission.

Note that most cross-toolchain combinations you might actually want within Debian are built by the Embedded Debian Project, so you may well just be able to apt-get what you need on their Toolchains page: .


To install a prebuilt cross compiler

If you have an Ubuntu (maverick/10.10, or later) system and want an armel or armhf toolchain then they are already part of your distro - just apt-get install arm-linux-gnueabi-gcc (for armel) or arm-linux-gnueabihf-gcc (for armhf). Backports for Lucid are available too.

For other architecutures, or if you have a Debian system you need to get toolchains from Emdebian.

Note that these toolchains search in the 'dpkg-cross' cross-lib/headers paths, not cthe new multiarch paths so are not very useful for multiarch cross-building. Currently (March 2012) you need to use the Ubuntu-supplied toolchains for that.

Add the Emdebian keyring from Debian before you start.

apt-get install emdebian-archive-keyring

Add two apt sources, one for your normal mirror and one for Emdebian:

deb squeeze main
deb squeeze main

Create a new file in /etc/apt/sources.list.d/ with the above lines.

Use whatever is your normal Debian mirror for the first line which brings in some dependencies which are no longer in Wheezy or unstable.

Now just install your toolchain, e.g. for armel:

apt-get update
apt-get install g++-4.4-arm-linux-gnueabi

Emdebian also maintain scripts which effectively do what this page describes. Take a look at the 'buildcross' package from Debian experimental, which will build a whole range of toolchains.

Most users do not need to build the cross-compiler

Commands you need to run as root assume you have already set up sudo on your system.

If you do need to build the compiler

We will be building a cross-compiler from the gcc-4.1 package. Specific version numbers for packages are listed as VERSION; substitute the version number of the latest package in unstable (or testing).

Notes for Debian unstable

We build gcc-4.4 whose cross package additionally build-depends on gcc-4.4-source which you henceforth must install.

The package linux-kernel-headers is now called linux-libc-dev instead.

The three packages libc6-dev, libc6, linux-libc-dev have additional dependencies, so you need to get the (native for the target arch) gcc-4.4-base, libc-bin, libc-dev-bin and libgcc2 (libgcc1, libgcc4, whatever your target needs) packages additionally. Now, dpkg-cross refuses to convert those without “any useful files”, so you need to pass the -A option in addition to -b and -a $ARCH.

A bit uglily, you get libgcc2-m68k-cross depending on gcc-4.4-base-m68k-cross from dpkg-cross and later, after compiling, libgcc2-m68k-cross depending on gcc-4.4-m68k-linux-gnu-base. Just remove the dpkg-cross-generated one once you got the new ones.

Build a cross-compilation toolchain

Create a working directory

mkdir -p ~/src/cross-toolchain
cd ~/src/cross-toolchain

Some useful variables

These will be used in the commands in this document. Replace "arm" with the architecture for which you are building a cross-compiler.

unset ARCH      # make sure it’s not exported
ARCH=arm        # set to the value we want to use

Get the source for binutils and GCC

apt-get source binutils gcc-4.1

Install Build-Depends

sudo apt-get build-dep binutils gcc-4.1

Note that gcc-4.1 may have build-dependencies that apt-get can't figure out; this is not a problem, just make sure you install all the ones that apt-get understands. Unfortunately, apt-get build-dep may give an error if such a situation arises; in this case, take the list of packages apt-get provided before giving an error, and install them using "sudo apt-get install pkg1 pkg2 pkg3 ...".

Install fakeroot

fakeroot allows you to build packages without being root.

sudo apt-get install fakeroot

Install dpkg-cross

dpkg-cross adds cross-compilation support to some of the basic Debian package tools. dpkg-cross can also convert packages designed for the target architecture into packages usable for cross-compilation to that architecture.

sudo apt-get install dpkg-cross

Build and install binutils

cd binutils-VERSION
export TARGET=$(dpkg-architecture -a$ARCH -qDEB_HOST_GNU_TYPE 2>/dev/null)
# this is for binutils <= 2.20
#fakeroot debian/rules binary-cross >../ 2>&1 || echo 'Build error'
# this is for binutils >= 2.21
dpkg-buildpackage -b -uc -us -rfakeroot >../ 2>&1 || echo 'Build error'
unset TARGET
cd ..
sudo dpkg -i binutils-${TARGET}_VERSION_HOSTARCH.deb

Note: the instructions are not totally correct. For example, with ARCH=amd64 you get TARGET=x86_64-linux-gnu and binutils-x86-64-linux-gnu (replace _ with - simply). For i386, you get TARGET=i486-linux-gnu but you’ll probably want i386-linux-gnu instead.

Convert library packages

You will need cross-compilation packages for various libraries; dpkg-cross can convert native packages for the target architecture into packages usable for cross-compilation. Note that the mirror only has amd64 and i386 packages, so to build a cross-compilation toolchain for another architecture (e.g. arm), you will have to use a mirror other than

dpkg-cross -a $ARCH -b l*.deb
sudo dpkg -i l*$ARCH-cross*.deb

It may be needed to download and convert libc-bin and libc-dev-bin packages too, otherwise the packages’ dependencies can maybe not be resolved. Use dpkg-cross -a m68k -A -b l*.deb in that case.

If you have an architecture that needs a libgcc[124] package, such as libgcc2-m68k-cross, installed to build gcc itself, it’s useful to install that from a previous build first (otherwise, convert it now, the same way).

June 2011, it's gotten worse. dpkg-cross -M -b -a m68k -X libc-bin -X libc-dev-bin *_m68k.deb converts the two eglibc packages, even though multiarch, and dropping the above-mentioned dependencies, and the linux-libc-dev package.

Build and install GCC

Now that you have all the necessary prerequisites, you can build a cross-compiling GCC.

cd gcc-VERSION
debian/rules control
dpkg-buildpackage -us -uc -rfakeroot -b > ../ 2>&1 || echo 'Build error'
cd ..
sudo dpkg -i *-VERSION-$ARCH-linux-gnu*.deb *-$ARCH-cross_VERSION*.deb

If you run into this error, or a similar one…

dh_strip -plibgcc2-m68k-cross --dbg-package=libgcc2-dbg-m68k-cross
objcopy: Unable to recognise the format of the input file `debian/libgcc2-m68k-cross/usr/m68k-linux-gnu/lib/'
dh_strip: objcopy --only-keep-debug debian/libgcc2-m68k-cross/usr/m68k-linux-gnu/lib/ debian/libgcc2-dbg-m68k-cross/usr/lib/debug//usr/m68k-linux-gnu/lib/ returned exit code 1
make[1]: *** [stamps/08-binary-stamp-libgcc] Error 2
make[1]: Leaving directory `/home/tg/X/gcc-4.4-4.4.5'
make: *** [binary] Error 2
dpkg-buildpackage: error: fakeroot debian/rules binary gave error exit status 2

… then this will help:

tg@zigo:~/X/gcc-4.4-4.4.5 $ sudo apt-get install binutils-multiarch
[sudo] password for tg:
Reading package lists... Done
Building dependency tree
Reading state information... Done
Starting 2
The following NEW packages will be installed:
0 upgraded, 1 newly installed, 0 to remove and 0 not upgraded.
Need to get 0 B/2127 kB of archives.
After this operation, 7164 kB of additional disk space will be used.
Selecting previously deselected package binutils-multiarch.
(Reading database ... 32493 files and directories currently installed.)
Unpacking binutils-multiarch (from .../binutils-multiarch_2.21.0.20110216-2_amd64.deb) ...
Adding 'diversion of /usr/bin/nm to /usr/bin/nm.single by binutils-multiarch'
Adding 'diversion of /usr/bin/objdump to /usr/bin/objdump.single by binutils-multiarch'
Adding 'diversion of /usr/bin/objcopy to /usr/bin/objcopy.single by binutils-multiarch'
Adding 'diversion of /usr/bin/strings to /usr/bin/strings.single by binutils-multiarch'
Adding 'diversion of /usr/bin/strip to /usr/bin/strip.single by binutils-multiarch'
Adding 'diversion of /usr/bin/size to /usr/bin/size.single by binutils-multiarch'
Adding 'diversion of /usr/bin/ar to /usr/bin/ar.single by binutils-multiarch'
Adding 'diversion of /usr/bin/ranlib to /usr/bin/ranlib.single by binutils-multiarch'
Adding 'diversion of /usr/bin/addr2line to /usr/bin/addr2line.single by binutils-multiarch'
Adding 'diversion of /usr/bin/gprof to /usr/bin/gprof.single by binutils-multiarch'
Adding 'diversion of /usr/bin/readelf to /usr/bin/readelf.single by binutils-multiarch'
Setting up binutils-multiarch ( ...

Test the cross-compile environment

Test compilation

Create a file "hello.c", containing the following code:

#include <stdio.h>

int main()
    printf("Hello cross-compiling world!\n");
    return 0;

Compile it statically with the new cross-compiler.

$ARCH-linux-gnu-gcc -static hello.c -o hello

Check the binary's type with "file".

file hello

You should see something like:

hello: ELF 32-bit MSB executable, PowerPC or cisco 4500, version 1 (SYSV), for GNU/Linux 2.2.0, statically linked, not stripped

for the PowerPC architecture.

Install qemu

qemu is an emulator for various architectures. It supports both whole-system emulation as well as single-program emulation with system-call conversion.

sudo apt-get install qemu

Run the test program with qemu

To run the test program with qemu, just prefix it with "qemu-$ARCH" (assuming of course that your architecture is supported by qemu).

qemu-$ARCH ./hello

You should see:

Hello cross-compiling world!

Get all the libraries you need

apt-cross is in Lenny but no longer in Squeeze. pdebuild-cross in Squeeze contains an early version of xapt or you can use the xapt xapt package from experimental until Squeeze is released.

xapt usage (squeeze):

xapt -a armel $LIBRARY

xapt usage (wheezy and unstable):

xapt -a armel -m $LIBRARY

The -m is necessary if pulling in packages from testing or unstable because of the MultiArch changes.

If you are still using Lenny, apt-cross is necessary.

apt-cross reminders:

apt-get install apt-cross dpkg-cross


apt-cross -a $ARCH -u

Fetch your cross favorite library

apt-cross -a $ARCH -i $LIBRARY