DistCC Cross-compiling Guide
1.
Cross-compiling with distcc
Introduction
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.
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 distcc.
Arch-specific notes
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.
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:
Note:
The following instructions are to be performed only on the box running the
emerge. Do not perform these steps on the helper boxes.
|
Code Listing 1.1: Available compilers |
# cd /usr/lib/distcc/bin
# ls -l
total 0
lrwxrwxrwx 1 root root 15 Dec 23 20:13 c++ -> /usr/bin/distcc
lrwxrwxrwx 1 root root 15 Dec 23 20:13 cc -> /usr/bin/distcc
lrwxrwxrwx 1 root root 15 Dec 23 20:13 g++ -> /usr/bin/distcc
lrwxrwxrwx 1 root root 15 Dec 23 20:13 gcc -> /usr/bin/distcc
lrwxrwxrwx 1 root root 15 Dec 23 20:13 sparc-unknown-linux-gnu-c++ -> /usr/bin/distcc
lrwxrwxrwx 1 root root 15 Dec 23 20:13 sparc-unknown-linux-gnu-g++ -> /usr/bin/distcc
lrwxrwxrwx 1 root root 15 Dec 23 20:13 sparc-unknown-linux-gnu-gcc -> /usr/bin/distcc
|
Here is what you want to do:
Code Listing 1.2: Modifying distcc |
# rm c++ g++ gcc cc
|
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.
Code Listing 1.3: The new wrapper script |
#!/bin/bash
exec /usr/lib/distcc/bin/sparc-unknown-linux-gnu-g${0:$[-2]} "$@"
|
Next, we'll make the script executable and create the proper symlinks:
Code Listing 1.4: Creating the symlinks |
# chmod a+x sparc-unknown-linux-gnu-wrapper
# ln -s sparc-unknown-linux-gnu-wrapper cc
# ln -s sparc-unknown-linux-gnu-wrapper gcc
# ln -s sparc-unknown-linux-gnu-wrapper g++
# ln -s sparc-unknown-linux-gnu-wrapper c++
|
When you're done, /usr/lib/distcc/bin will look like this:
Code Listing 1.5: A proper set of compilers |
# ls -l
total 4
lrwxrwxrwx 1 root root 25 Jan 18 14:20 c++ -> sparc-unknown-linux-gnu-wrapper
lrwxrwxrwx 1 root root 25 Jan 18 14:20 cc -> sparc-unknown-linux-gnu-wrapper
lrwxrwxrwx 1 root root 25 Jan 18 14:20 g++ -> sparc-unknown-linux-gnu-wrapper
lrwxrwxrwx 1 root root 25 Jan 18 14:20 gcc -> sparc-unknown-linux-gnu-wrapper
lrwxrwxrwx 1 root root 15 Nov 21 10:42 sparc-unknown-linux-gnu-c++ -> /usr/bin/distcc
lrwxrwxrwx 1 root root 15 Nov 21 10:42 sparc-unknown-linux-gnu-g++ -> /usr/bin/distcc
lrwxrwxrwx 1 root root 15 Jul 27 10:52 sparc-unknown-linux-gnu-gcc -> /usr/bin/distcc
-rwxr-xr-x 1 root root 70 Jan 18 14:20 sparc-unknown-linux-gnu-wrapper
|
Congratulations; you now have a (hopefully) working cross-distcc setup.
How this works
When distcc is called, it checks to see what it was called as (e.g.
i686-pc-linux-gnu-gcc, 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.
The contents of this document, unless otherwise expressly stated, are licensed under the CC-BY-SA-2.5 license. The Gentoo Name and Logo Usage Guidelines apply.
|