Differences between revisions 39 and 51 (spanning 12 versions)
Revision 39 as of 2013-05-24 12:08:47
Size: 12797
Editor: wookey
Comment:
Revision 51 as of 2016-01-27 16:08:17
Size: 4251
Editor: ?Lemmata
Comment: fixed errors in example code where target and host arch were accidentally swapped
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
#language en
~-[[DebianWiki/EditorGuide#translation|Translation(s)]]: none-~
----
<<TableOfContents()>>
(Crosstoolchain documentation is now collected and indexed on CrossToolchains)
Line 6: Line 3:
= Installing a Cross Compiler = = Building a Cross Compiler =
Line 8: Line 5:
This document will help you obtain Debian packages of a cross-compilation toolchain. It is based on [[http://psas.pdx.edu/DebianCrossCompilerHowto|a HOWTO]] by Josh Triplett, with his kind permission. Very few people need to build a cross-toolchain. It is a complicated business and unless you are doing something really quite obscure you should just install a suitable apt-able toolchain. Installation info is on CrossToolchains.
Line 10: Line 7:
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 We'll say that again: '''MOST PEOPLE SHOULDN'T BE BUILDING THEIR OWN CROSS-TOOLCHAIN - THEY SHOULD JUST INSTALL A PRE-BUILT ONE LIKE ANY OTHER PACKAGE'''.
Line 12: Line 9:
We'll say that again: '''MOST PEOPLE SHOULDN'T BE BUILDING THEIR OWN CROSS-TOOLCHAIN - THEY SHOULD JUST INSTALL A PRE-BUILT ONE LIKE ANY OTHER PACKAGE'''. But there are reasons why you might need to do this.
Line 14: Line 11:
== To install a prebuilt cross compiler == = I really do want to build a cross compiler =
Line 16: Line 13:
=== What if I have an Ubuntu system or want to do multiarch-style crossbuilding? === Pick the most relevant heading from the list below.
Line 18: Line 15:
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)) == Nomenclature ==
Line 20: Line 17:
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. TARGET is the architecture the compiler builds code for.
HOST (same as BUILD in this case) is the architecture the compiler runs on (and is currently being built on)
Line 22: Line 20:
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. == I want a combination of HOST x TARGET not in Debian (on jessie or later) ==
Line 24: Line 22:
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: [[http://wiki.debian.org/MultiarchCrossToolchains|multiarch-ready Debian cross-toolchains]]. === TARGET is a debian release architecture ===

If TARGET is a debian release architecture then this is fairly straightforward:

 * Install the cross-gcc-dev binary package
{{{
apt-get install cross-gcc-dev
}}}
This is available from jessie (Debian 8) onwards

 * Generate a cross-gcc-<gccver>-<arch> source package
{{{
TARGET_LIST=<targetarch> HOST_LIST=<hostarch> cross-gcc-gensource <gccver>
}}}
Fill in your own <targetarch>, <hostarch> and <gccver> above. (e.g. {{{TARGET_LIST="armel armhf" HOST_LIST="amd64" cross-gcc-gensource 4.9}}})
In jessie only '4.9' is supported as a gcc version.

This will generate (in a directory called cross-gcc-packages-<buildarch>) a cross-gcc-<gccver>-<arch> source package for each arch in the TARGET_LIST.

'''Note''': in jessie cross-gcc-gensource will fail if dash is your default shell. (DebianBug:#780583). Either set the /bin/sh link to bash {{{sudo ln -sf bash /bin/sh}}} or add
{{{SHELL := bash}}} near the start of /usr/share/cross-gcc/template/rules.generic
(fixed in cross-gcc 17)

 * Build it
{{{
cd cross-gcc-<gccver>-<arch>
sbuild -d jessie
}}}
You will need sbuild 0.64.3 or later installed, and a suitable chroot or build env for the target suite. You will also need a <triplet>-binutils package.

=== Building corresponding binutils and gcc-metapackages ===

If the cross-binutils you need is not available on your arch, build one (or more) like this:
{{{
apt-get source cross-binutils
cd cross-binutils-0.23
sudo apt-get build-dep cross-binutils
TARGET_LIST="arm64" HOST_LIST="armhf" debian/rules control
TARGET_LIST="arm64" HOST_LIST="armhf" dpkg-buildpackage
}}}

To make your toolchain convenient to use you need a set of metapackages which provide links from tools to versioned tools (so gcc-arm-linux-gnueabihf links to gcc-4.9-arm-linux-gnueabihf etc). The cross-gcc-defaults package provides those:
{{{
apt-get source cross-gcc-defaults
cd cross-gcc-defaults-0.7
TARGET_LIST='armhf' debian/generate-pkgfiles.pl
dpkg-buildpackage
}}}
cross-gcc-defaults is available in the jessie external toolchain repository and in unstable.

A more manual build of cross-gcc, probably best done in a chroot, could be
{{{
cd packages/cross-gcc-4.9-<hostarch>
dpkg --add-architecture <hostarch>
apt-get update
[install build-deps]
dpkg-buildpackage
}}}
(This essentially automates the procedure described on MultiarchCrossToolchainBuild).

=== TARGET is not a debian release architecture ===

If TARGET is not a debian release architecture (debian-ports architecture or a new arch), then it may be much harder because you need to do a full kernel/libc/gcc bootstrap. The cross-toolchain-base package (in unstable) can do this for some architectures. The rebootstrap tool can do it for any architecture.
Line 27: Line 87:
=== Installing cross-toolchains from Emdebian === === I want the very latest arm support ===
Line 29: Line 89:
Add the Emdebian keyring from Debian before you start.
{{{
apt-get install emdebian-archive-keyring
}}}
Linaro's cross-toolchains (tarball install, sadly) are very up to date with patches and support, and may well be useful. But they are supplied as a binary tarball, not as debian packages.
Line 34: Line 91:
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
}}}
=== I want toolchain packages for wheezy ===
Line 40: Line 93:
Create a new file in {{{/etc/apt/sources.list.d/}}} with the above lines. The packages on emdebian.org aimed at wheezy have been uninstallable for a long time.
Install buildcross from experimental and use that to build your own.
Line 42: Line 96:
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 DebianPts: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 >../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
export GCC_TARGET=$ARCH
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
Starting 2
Done
The following NEW packages will be installed:
  binutils-multiarch
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 (2.21.0.20110216-2) ...
}}}

== 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
}}}

Update
{{{
apt-cross -a $ARCH -u
}}}

Fetch your cross favorite library
{{{
apt-cross -a $ARCH -i $LIBRARY
}}}



----
CategoryEmdebian
<some instructions here would be helpful>

(Crosstoolchain documentation is now collected and indexed on CrossToolchains)

Building a Cross Compiler

Very few people need to build a cross-toolchain. It is a complicated business and unless you are doing something really quite obscure you should just install a suitable apt-able toolchain. Installation info is on CrossToolchains.

We'll say that again: MOST PEOPLE SHOULDN'T BE BUILDING THEIR OWN CROSS-TOOLCHAIN - THEY SHOULD JUST INSTALL A PRE-BUILT ONE LIKE ANY OTHER PACKAGE.

But there are reasons why you might need to do this.

I really do want to build a cross compiler

Pick the most relevant heading from the list below.

Nomenclature

TARGET is the architecture the compiler builds code for. HOST (same as BUILD in this case) is the architecture the compiler runs on (and is currently being built on)

I want a combination of HOST x TARGET not in Debian (on jessie or later)

TARGET is a debian release architecture

If TARGET is a debian release architecture then this is fairly straightforward:

  • Install the cross-gcc-dev binary package

apt-get install cross-gcc-dev

This is available from jessie (Debian 8) onwards

  • Generate a cross-gcc-<gccver>-<arch> source package

TARGET_LIST=<targetarch> HOST_LIST=<hostarch> cross-gcc-gensource <gccver>

Fill in your own <targetarch>, <hostarch> and <gccver> above. (e.g. TARGET_LIST="armel armhf" HOST_LIST="amd64" cross-gcc-gensource 4.9) In jessie only '4.9' is supported as a gcc version.

This will generate (in a directory called cross-gcc-packages-<buildarch>) a cross-gcc-<gccver>-<arch> source package for each arch in the TARGET_LIST.

Note: in jessie cross-gcc-gensource will fail if dash is your default shell. (). Either set the /bin/sh link to bash sudo ln -sf bash /bin/sh or add SHELL := bash near the start of /usr/share/cross-gcc/template/rules.generic (fixed in cross-gcc 17)

  • Build it

cd cross-gcc-<gccver>-<arch>
sbuild -d jessie 

You will need sbuild 0.64.3 or later installed, and a suitable chroot or build env for the target suite. You will also need a <triplet>-binutils package.

Building corresponding binutils and gcc-metapackages

If the cross-binutils you need is not available on your arch, build one (or more) like this:

apt-get source cross-binutils
cd cross-binutils-0.23
sudo apt-get build-dep cross-binutils
TARGET_LIST="arm64" HOST_LIST="armhf" debian/rules control
TARGET_LIST="arm64" HOST_LIST="armhf" dpkg-buildpackage

To make your toolchain convenient to use you need a set of metapackages which provide links from tools to versioned tools (so gcc-arm-linux-gnueabihf links to gcc-4.9-arm-linux-gnueabihf etc). The cross-gcc-defaults package provides those:

apt-get source cross-gcc-defaults
cd cross-gcc-defaults-0.7
TARGET_LIST='armhf' debian/generate-pkgfiles.pl
dpkg-buildpackage

cross-gcc-defaults is available in the jessie external toolchain repository and in unstable.

A more manual build of cross-gcc, probably best done in a chroot, could be

cd packages/cross-gcc-4.9-<hostarch>
dpkg --add-architecture <hostarch>
apt-get update
[install build-deps]
dpkg-buildpackage

(This essentially automates the procedure described on MultiarchCrossToolchainBuild).

TARGET is not a debian release architecture

If TARGET is not a debian release architecture (debian-ports architecture or a new arch), then it may be much harder because you need to do a full kernel/libc/gcc bootstrap. The cross-toolchain-base package (in unstable) can do this for some architectures. The rebootstrap tool can do it for any architecture.

I want the very latest arm support

Linaro's cross-toolchains (tarball install, sadly) are very up to date with patches and support, and may well be useful. But they are supplied as a binary tarball, not as debian packages.

I want toolchain packages for wheezy

The packages on emdebian.org aimed at wheezy have been uninstallable for a long time. Install buildcross from experimental and use that to build your own.

<some instructions here would be helpful>