DistCC Cross-compiling Guide Andrew Gaffney Joshua Saddler This guide shows you how to set up distcc for cross-compiling across different processor architectures. 1.0 2005-12-24 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.

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 couple of wrapper scripts 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:

ryoko 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:

# rm c++ g++ gcc cc

Next, we'll create the new scripts. Fire up your favorite editor and create a file with the following text in it, then save it as gcc.

#!/bin/bash

exec /usr/lib/distcc/bin/sparc-unknown-linux-gnu-gcc "$@"

Again, create another file and add the following to it, then save it as g++.

#!/bin/bash

exec /usr/lib/distcc/bin/sparc-unknown-linux-gnu-g++ "$@"

Next, we'll create the proper symlinks:

# ln -s gcc cc
# ln -s g++ c++
# chmod a+x gcc g++

When you're done, /usr/lib/distcc/bin will look like this:

ryoko bin # ls -l
total 8
lrwxrwxrwx  1 root root  3 Dec 23 20:16 c++ -> g++
lrwxrwxrwx  1 root root  3 Dec 23 20:16 cc -> gcc
-rwxr-xr-x  1 root root 71 Dec 23 20:16 g++
-rwxr-xr-x  1 root root 71 Dec 23 20:16 gcc
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

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. It does this by examining argv[0]. 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.