This guide shows you how to set up distcc for cross-compiling across different processor architectures.
Cross-compiling with distcc
distcc is a tool that lets you share the burden of software compiling across several networked computers. As long as the networked boxes are all using the same toolchain built for the same processor architecture, no special
distcc setup is required. But what do you do if you need to compile for a different architecture using differing computers? This guide will show you how to configure
distcc to compile for different architectures.
Emerge the needed utilities
First, you will need to emerge
crossdev on all the machines that will be involved in the compiling process.
crossdev is a tool that makes building cross-architecture toolchains easy. It was originally written by Joshua Kinard and was re-written from the ground up by Mike Frysinger. Its usage is straightforward:
crossdev -t sparc will build a full cross-toolchain targetting the Sparc architecture. This includes binutils, gcc, glibc, and linux-headers. If you need more help, try running
crossdev --help. Obviously, you will need to emerge the proper cross-toolchain on all the helper boxes.
If you want to fine tune the cross-toolchain, here is a script that will produce a command line with the exact versions of the cross development packages to be built on the helper boxes (the script is to be run on the target box).
Next, you will need to emerge
distcc on all the machines that will be involved in the process. This includes the box that will run emerge and the boxes with the cross-compilers. Please see the Gentoo Distcc Documentation for more information on setting up and using
Intel x86 subarchitectures
If you are cross-compiling between different subarchitectures for Intel x86 (e.g. i586 and i686), you must still build a full cross-toolchain for the desired CHOST, or else the compilation will fail. This is because i586 and i686 are actually different CHOSTs, despite the fact that they are both considered "x86." Please keep this in mind when you build your cross-toolchains. For example, if the target box is i586, this means that you must build i586 cross-toolchains on your i686 helper boxes.
crossdev -t sparc might fail with one of the following errors:
If this happens, try using the following command instead:
Configuring distcc to cross-compile correctly
In the default distcc setup, cross-compiling will not work properly. The problem is that many builds just call
gcc instead of the full compiler name (e.g.
sparc-unknown-linux-gnu-gcc). When this compile gets distributed to a distcc helper box, the native compiler gets called instead of your shiny new cross-compiler.
Fortunately, there is a workaround for this little problem. All it takes is a wrapper script and a few symlinks on the box that will be running
emerge. I'll use my Sparc box as an example. Wherever you see
sparc-unknown-linux-gnu below, you will want to insert your own CHOST (
x86_64-pc-linux-gnu for an AMD64 box, for example). When you first emerge distcc, the /usr/lib/distcc/bin directory looks like this:
Here is what you want to do:
Next, we'll create the new script on this box. Fire up your favorite editor and create a file with the following text in it, then save it as sparc-unknown-linux-gnu-wrapper. Remember to change the CHOST (in this case,
sparc-unknown-linux-gnu) to the actual CHOST of the box that will be running the emerge.
Next, we'll make the script executable and create the proper symlinks:
When you're done, /usr/lib/distcc/bin will look like this:
Congratulations; you now have a (hopefully) working cross-distcc setup.
The only issue with the wrappers is that when distcc updates every few months it will nuke them back to original status. I could never get config_protect to shield them. You must remember to manually restore them. I rarely did; I would often discover months later when tracking down some problem with distcc. So I made an /etc/portage/bashrc with the following:
Obviously this is on my amd64 machine, you would change the ln -s statements for the machine you use. This has been working great for me and I no longer have to worry about it.
How this works
distcc is called, it checks to see what it was called as (e.g.
sparc-unknown-linux-gnu-g++, etc.) When distcc then distributes the compile to a helper box, it passes along the name it was called as. The distcc daemon on the other helper box then looks for a binary with that same name. If it sees just
gcc, it will look for
gcc, which is likely to be the native compiler on the helper box, if it is not the same architecture as the box running
emerge. When the full name of the compiler is sent (e.g.
sparc-unknown-linux-gnu-gcc), there is no confusion.
We would like to thank the following authors and editors for their contributions to this guide:
- Andrew Gaffney
- Joshua Saddler