Differences between revisions 39 and 40
Revision 39 as of 2013-05-24 12:08:47
Size: 12797
Editor: wookey
Revision 40 as of 2013-12-19 23:25:17
Size: 3229
Editor: ?shawnlandden
Comment: this is obsoleted by the multiarch cross toolchains
Deletions are marked like this. Additions are marked like this.
Line 54: Line 54:
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 >../binutils.build 2>&1 || echo 'Build error'
# this is for binutils >= 2.21
dpkg-buildpackage -b -uc -us -rfakeroot >../binutils.build 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 ftp.us.debian.org 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 ftp.us.debian.org.
wget http://ftp.XX.debian.org/debian/pool/main/e/eglibc/libc6-dev_VERSION_$ARCH.deb
wget http://ftp.XX.debian.org/debian/pool/main/e/eglibc/libc6_VERSION_$ARCH.deb
wget http://ftp.XX.debian.org/debian/pool/main/l/linux-kernel-headers/linux-kernel-headers_VERSION_$ARCH.deb
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 > ../gcc.build 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/libgcc_s.so.2'
dh_strip: objcopy --only-keep-debug debian/libgcc2-m68k-cross/usr/m68k-linux-gnu/lib/libgcc_s.so.2 debian/libgcc2-dbg-m68k-cross/usr/lib/debug//usr/m68k-linux-gnu/lib/libgcc_s.so.2 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. [[DebianPkg:pdebuild-cross|pdebuild-cross]] in Squeeze contains an early version of {{{xapt}}} or you can use the DebianPkg: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|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

Translation(s): none

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: http://www.emdebian.org/crosstools.html


To install a prebuilt cross compiler

What if I have an Ubuntu system or want to do multiarch-style crossbuilding?

If you have an Ubuntu system, cross-toolchains are included (from 10.10/maverick onwards). From Quantal/ onwards there is a crossbuild-essential-<arch> convenience package to install cross toolchains, cross-pkgconfig and (multiarch) cross-libc. So simply installing crossbuild-essential-armhf, or crossbuild-essential-arm64 will get you all the stuff you need. (multiarch for the architecture you want to build for must be enabled, with dpkg --add-architecture <arch> (e.g. armhf))

Prior to quantal there are just cross-toolchain packages which install the cross-toolchain and default compiler links. apt-get install arm-linux-gnueabi-gcc (for armel) or arm-linux-gnueabihf-gcc (for armhf). These toolchains search multiarch library and header paths by default so are suitable for multiarch crossbuilding.

For other architectures, or if you have a Debian system you should get toolchains from Emdebian. These toolchains search in the 'dpkg-cross' cross-lib/headers paths, not the new multiarch paths, so are not very useful for multiarch cross-building.

Debian multiarch-ready cross-toolchains for armhf and armel are available here: http://emdebian.org/~thibg/repo/pool/main/g/gcc-4.7/ Work is underway to integrate cross-toolchains properly into debian: multiarch-ready Debian cross-toolchains.

Installing cross-toolchains from Emdebian

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 http://ftp.XX.debian.org/debian squeeze main
deb http://www.emdebian.org/debian 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