Hi,
It's been three weeks already since the end of the Google Summer of Code 2012,
and I've been told I still haven't blogged about the state of multiarch cross-toolchains.
So, here it is!

Building multiarch cross-toolchains

This section is mostly a rehash of my previous post.
Cross-toolchains build properly for most architectures in Debian, with the exception
of arches having clashing ld.so paths.
The following instructions assume you are using Wheezy or unstable, and have applied
my patches.

Adding a foreign architecture

You are going to use some packages meant for a different architecture than your native one.
This means you'll have to tell dpkg about a foreign architecture, for instance, armel.

# dpkg --add-architecture armel

Then, you need to update apt's database.

# apt-get update

If one of the repository you use only supports a subset of your configured
architecture (for instance, when working with an unofficial port), you will need
to use arch restrictions in your sources.list (see the manpage).

Cross-binutils

Absolutely nothing has changed there, it works exactly the same way it did before the GSoC.
That is, grab binutils' source package, set $TARGET to a GNU triplet or a Debian arch, and
run dpkg-buildpackage.

Cross-gcc

Building cross-gcc is done the same way it was before the GSoC, except it uses cross-arch
dependencies instead of mangled packages for foreign packages. This means you shouldn't
use dpkg-cross at all, but use multiarch instead.

Biarch/multilib and multiarch do not really play well. Using some trickery, you might
be able to build multilib cross-compilers, but I would recommend building two
cross-compilers instead.

You will of course need to install the required build-dependencies, some of which are
packages for the target architecture, but that is no different from building any other
Debian package, provided that multiarch is correctly configured.

This will produce cross-compilers packages using multiarch paths and cross-arch deps, along
with some binary packages for the target architecture. Those binary packages are cross-built
versions of the runtime libs. They are not needed, as they should be identical to the
natively-built ones present in the archive, but using them shouldn't be a problem.

Installing the cross-toolchains

Installing cross-binutils is straightforward, installing cross-gcc itself is, but installing cross-g++ is not.
Indeed there is bug #678623: g++-4.7 depends on libstdc++6-4.7-dev, which is multiarch-unaware and depends on g++-4.7.
Assuming you've compiled your cross-gcc using my patches, the cross-compiled libstdc++6-4.7-dev will not have
these problems, but still won't be co-installable with your native libstdc++6-4.7-dev, since it's
not M-A: same. The easiest way to work around this issue is probably to download the binary package,
modify its control file to include “Multi-Arch: same”, and install the modified package.

Using the cross-toolchains

Once installed, using the cross-toolchains should be as easy as running “$triplet-gcc-4.7 file.c”.
Note the “-4.7” part. Indeed, the cross-compilers packages do not provide the “$triplet-gcc” symlink.
This matches what is done with the native compiler pase, where the “gcc” symlink is not provided by the
compiler's package, but by the “gcc” package. However, there is no “cross-gcc” package or anything like that
yet, which means you have to use the full name, or provide the symlink yourself.

Another issue is pkg-config. To know where to search for libraries, pkg-config has to be told which architecture
you are compiling for. Autotools does that by calling “$triplet-pkg-config” instead of “pkg-config” if it
exists. The “pkg-config” binary packages comes with a wrapper you can symlink to: “/usr/share/pkg-config-crosswrapper”.

Conclusion

Despite a few shortcomings (bug #678623, missing symlinks, multilib issues and clashing ld.so paths),
multiarch cross-toolchains are already usable on Wheezy.
There is still quite a lot of work left (like fixing #678623, splitting gcc-4.7 in two,
or changing wanna-build, britney etc. to handle cross-arch deps) but hopefully this will be done for Jessie.

Hi!
As you may know, I'm working on multiarch cross-toolchains as part of the Google summer of Code (see my previous post for details), and although there is still a lot to do, the project is doing fairly well, and a cross-gcc is already installable and working.
I'll proceed with detailed instructions on how to install the cross-compiler, along with some explanations on multiarch itself, and how to build cross-toolchains from source.

Prerequisites

First, you need specific versions apt (>= 0.9.6) and dpkg (>= 1.16.5).
This is because the cross-toolchains packages I'm working on depend on specific cross-arch dependencies, such as libc6:armhf.
Support for such dependencies has been added in the aforementioned versions of apt and dpkg.
This means you should be running unstable, or at least use dpkg from unstable.

Adding a foreign architecture

Adding a foreign architecture is straightforward, but I've seen users do overcomplicated, or just plain wrong things.
So, let's do this step by step (well, there are only two of them), with some explanations.

Tell dpkg to handle an additional architecture by typing dpkg --add-architecture armhf.
There isn't much to say. It will only add an architecture to the list of architectures dpkg would accept to handle.

Update APT's database. You need to run apt-get update after adding or removing an architecture to get package lists for all wanted architectures and rebuild APT's database, including the implicit cross-arch dependencies/conflicts brought by multiarch.

And that's it for the common case. Now, a word on architecture restrictions: a common misconception about multiarch seems to be that you have to tell APT which architectures you want from the mirrors by modifying your sources.list file(s). This is not true, as, by default, APT gets the list of accepted architectures from dpkg, and gets the correct package lists from the mirrors configured in the sources.list. You only need to use arch restrictions (“deb [arch=arch1,arch2,...] ...”) when you want to get packages from a mirror only for a subset of your accepted architectures. This is very unlikely, and in the general you do not need to modify your sources.list, at all.

I provide compiled versions of gcc-4.7-arm-linux-gnueabihf for i386 and amd64 in my repository.
If you have followed the previous paragraphs, nothing should be easier than adding a “deb http://emdebian.org/~thibg/repo/ sid main” line to your sources.list and doing the following:

Using the cross-compiler

It's easy, but there is a trick, and dpkg-buildpackage -aarmhf won't work out of the box yet, as gcc-4.7-arm-linux-gnueabihf provides the “arm-linux-gnueabihf-gcc-4.7” executable, but no “arm-linux-gnueabihf-gcc” symlink.

Conclusion

The toolchain is not complete yet (there is some more work to do on binutils and libstdc++, and equivalents to the “gcc”, “cpp”, and “build-essential” packages to provide), but it should still be useful to cross-compile C programs.
Multi-arch cross-toolchains for wheezy can definitely be hosted at emdebian, and I hope to clean up the build process so that it could get included in the archive for wheezy+1.

What is multiarch?

In order to understand what the project is about, one need to know what multiarch is.
I'll quickly describe it, and I invite anyone interested to read the spec (really, it's interesting, and not that long).
Basically, multiarch lets you install binary packages for multiple architectures on one system,
and let package managers resolve dependencies as one would expect.

This works by identifying four sets of packages:

Packages that don't need to be aware of multi-arch. Such packages can only be installed for one architecture at a time, and can only be used to resolve dependencies of packages having the same architecture.

Those packages are “Multi-Arch: none” or “multiarch-unaware” packages.

Packages that can be installed for multiple architectures at a time, and can only be used to resolve dependencies of packages having the same architecture.

Those packages are “Multi-Arch: same” packages. They typically are libs.

Packages that can only be installed for one architecture at a time but can satisfy dependencies of any package regardless of its architecture.

Those packages are “Multi-Arch: foreign” packages.
They typically are tools working with architecture-independent interfaces. (for instance, gpg, zenity or tar).

Packages that can only be installed for one architecture at a time but can satisfy any dependency annotated with “:any”, regardless of the architecture.

Those packages are “Multi-Arch: allowed” packages.
They are packages providing both arch-dependent and arch-independent interfaces.
They are typically things like python, which can be used to interpret arch-indep files, but providing arch-dependent interfaces for C extensions.

Anyway, multiarch is an amazing thing that may be of use in various cases, such as running i386-only software on an amd64 system,
running armel software on an armhf system, running i386 software on an armhf system using qemu-user-static and binfmt,
cross-grading (switching, for instance, from i386 to amd64 on a running system), and, in our case, easing cross-compilation.

State of cross-toolchains in Debian

However, those packages predate multiarch, and don't make use of it.
Instead, they depend on special packages converted using dpkg-cross.
Such packages are merely arch: all versions of foreign packages,
with files moved to arch-qualified paths to prevent conflicts with “normal” packages.

Such packages thus have to be generated from real packages, either manually or using some sort of automation.
In addition, this additional step brings several issues,
like keeping in sync converted packages with real packages from the archive.

With multiarch, such packages are rendered useless, and may in fact bring additional problems,
since “converted” and multiarch packages may share the same files, and thus may not be co-installable.

Switching from dpkg-cross to cross-arch deps

Cross-toolchains packages currently depend on a few packages converted using dpkg-cross
(ex: libc6-$ARCH-cross and libc6-dev-$ARCH-cross for some packages).
They need to depend on the “real” package with the right arch (ex: libc6:$ARCH, libc6-dev:$ARCH).

The obvious way to do so is by annotating the dependency with a specific arch qualifier (ex: “Depends: libc6:armhf”).
This is, however, not covered by the multiarch spec.

Note that some “lib*-$ARCH-cross” packages will remain (for instance, libgcc1-armhf-cross).
Indeed, those packages are different from the packages mentioned above in that
they are of the architecture of the build system and actually part of the toolchain itself.The above isn't actually true. Indeed, those packages are runtime library cross-built during gcc's build.

Likewise, cross-toolchains may build-depend on foreign packages (ex: libc6-dev).
Thus, specific arch qualifiers must be handled in the “Build-Depends” source package field too.

Changing dpkg and apt to support that should be fairly straightforward.
In fact, I already have a few patches, but I need to refresh them, maybe clean them up a little,
and push them a little harder to get them accepted!