CrossToolchains

This document describes a possible near future - most of it is not actually true within the debian archive today (20th August).

Packages which do (probably) implement (most of) what is decribed here are available at https://people.debian.org/~wookey/tools/debian/

Packages which implement some of what is described here (without the gcc-for-host/build multiarch magic - just cross toolchains) are available at http://toolchains.secretsauce.net/


Debian provides cross-toolchains in the archive from Jessie onwards. Previously they haveonly been available from external repositories.

These are generally built to run on fast architectures (amd64, ppc64, arm64), and target all reasonably popular architectures (arm64, armel, armhf, powerpc, ppc64, i386, amd64, mips, mipsel, mips64el).

They will be automatically installed (by the magic of multiarch) if you enable the architecture you are building for, and install build-essential for a target architecture, or a package which directly depends on gcc-for-host.

!Note the BUILD architecture is the machine you are building _on_. the HOST architecture is the one you are building _for_

Installation

To cross-build (or install cross toolchains) you will need to enable multiarch for the architcture you are building for (the HOST arch) (unless targetting an architecture that is not in Debian, in which case the cross-toolchain will be installable without any foreign-arch packages).

dpkg --add-architecture armhf
apt-get update

Use the debian architecture name to install toolchains (or cross-toolchains)

apt-get install -a<arch> build-essential

i.e

apt-get install -aarmhf build-essential

Note that the toolchains thus installed must be used as <triplet>-gcc, for both native _and_ cross usage. i.e. x86_64-linux-gnu-gcc for the native compiler on amd64, and arm-linux-gnueabihf-gcc for the cross-compiler targetting armhf.

Plain 'gcc' will (probably) not be installed.

Which packages are what?

The actual versioned cross-compiler is in gcc-4.9-arm-linux-gnueabihf The package setting which version of the toolchain is currently the default is gcc-arm-linux-gnueabihf The package which pulls in a specific version of the target arch cross-compiler is gcc-4.9-for-host:armhf The package which pulls in the target arch cross-compiler is gcc-for-host:armhf The package which pulls in the build (native) arch compiler is gcc-for-build

Packages which need a particular version of gcc should build-depend on gcc-4.9-for-host Packages which _also_ need the build-arch gcc when cross-building, should build-depend on gcc-for-build (for the default version) or gcc-4.9-for-build (to get 4.9 specifically).

Similar packages exist for g++, cpp, gfortran, binutils and pkg-config.

Installing build-dependencies

apt-get build-dep -a <arch> <package>

e.g.

apt-get build-dep -a armhf util-linux

If the build-deps are not installable in this way (usually due to un-multiarched packages in the dependency tree), then use dpkg-checkbuilddeps and apt-get install to manually insert the right packages.

Information for package maintainers

In the pre-multiarch-crosscompiler world (prior to Jessie) a package could run 'gcc' and expect to get the compiler targetting the native arch and running on the native arch (e.g amd64,amd64). And it could build-depend on 'gcc-4.7' to get an older compiler installed. However There was no way to depend on a particular compiler version and have that version of the cross-compiler installed, so this scheme made any package needing a particular gcc version uncrossbuildable (without a lot of faffing).

In Jessie build-essential implicitly depends on the compiler for the HOST architecture (which is the architecture you are building _for_) via 'gcc-for-host'. This is the default compiler, which must be run specifying the TARGET architecture (the one you want to build code for), i.e. as x86_64-linux-gnu-eabi-gcc. Don't call 'gcc' as it may not do the right thing, or work at all.

Packages that need a specific version of the compiler can now depend on 'gcc-<version>-for-host' and will get the <triplet>-gcc for the (HOST) architecture that the build is targetting.

How does this _really_ work

Details of the gcc interface and metapackage design are in https://wiki.debian.org/Sprints/2014/BootstrapSprint/Results

Appropriate info need extracting to here

Cross-toolchain building

There are various parts to the cross-toolchains, wich come from several source packages. The cross-gcc packages themselves can be built in two different ways.

1 Multiarch gcc builds 2 Bootstrap cross-toolchain builds

The differences are explained on ?MultiarchCrossTroolchainBuilds.

The former builds (for example) gcc-arm-linux-gnueabihf (and cpp,g++,gfortran) against the linux-libc-dev:armhf, libc6-dev:armhf, libstdc++-dev:armhf and libgcc1:armhf already in the archive. The build is quick and simple, but the resulting package has cross-arch dependencies (on the various :armhf packages), so you need to enabled multiarch to install them. You will need to enable multiarch for most cross-builds anyway

The latter builds (for example) linux-libc-dev-cross-armhf, libc-dev-cross-armhf, libstdc++-dev-cross-armhf, libgcc1-cross-armhf and gcc-arm-linux-gnueabihf (and cpp,g++,gfortran) from the kernel, glibc, and gcc sources, via the toolchain bootstrap process. Because the foreign-arch libraries are converted to build-arch packages, the toolchain does not need multiarch enabled to build, but the build is much longer and more complicated, and you end up with two copies of those libraries on your system.

This type of build is necessary when the target architecture is not in the debian archive as the libraries are not available to build against.

Sources

* src:cross-binutils provides the binutils-<triplet> packages * src:gcc-cross-support provides the gcc-4.9-for-host and gcc-4.9-for-build packages * src:gcc-defaults provides the gcc-arm-linux-gnueabihf and gcc-for-host default-version packages. * src:gcc-4.9 provides the native toolchain packages * src:cross-4.9-gcc-armhf provides the (version 4.9) cross-gcc (and cpp, g++, gfortran) compilers targetting armhf (arm-linux-gnueabihf) * src:cross-4.9-gcc-bootstrap-sparc provides (version 4.9) self-contained cross-gcc (and cpp, g++, gfortran) compilers targetting sparc (and other architectures which are not offical debian releases)

Multiarch vs Multilib

Targetting related architectures (such as i386/amd64, armel/armhf, mips/mipsel) can be done in two different ways. You can either build one cross-compiler for each target, and install whichever ones you need, or you can build one cross-compiler which has two or more multilibs installed, install just that one cross-compiler and use build options to control which code is output.

i.e on amd64 you can target i386 either by running i386-linux-gnu-gcc, or by running x86_64-linux-gnu-gcc -m32

These options are not consistent across different architecture sets, whilst use of <triplet>-gcc always works: arm-linux-gnueabi-gcc produces the same (armel) output on all arches arm-linux-gnueabihf-gcc -mabi=softfp can be used instead on armhf to produce armel binaries.

Building these multilibbed cross-toolchains is are a lot more fiddly than plain multiarch ones. Thus the current debian cross-toolchains are not multilibbed and only support the <triplet>-gcc method. Install whichever targets you need, and use the same commands everywhere. Encourage upstreams to call tools this way, rather than using -mabi=blah options, although in x86 world the use of m32/m64 is rife and is probably too late to change. Some packages may need their build options adjusting to do this right.