Cross-compiling with icecc/icecream

Very common questions I hear when dealing with  compiling open source projects are:

  1. How do I cross-compile a project using icecc/icecream?
  2. How to use a different compiler version for compiling my project and still benefiting from icecc/icecream?

Note: from now on I’ll always refer to icecream instead icecc/iceccd/distcc for the name of the project.

Given you already created your cross toolchain  (or downloaded from somewhere else, e.g.  CodeSourcery/Linaro) these two questions are essentially the same. All you have to do is to follow the two steps below:

1. Create the “compiler environment”

Understanding this part is really understanding how this magic remote-compiling works. When you want to compile a source remotely, what icecream does is sending a copy of your compiler and the things it needs to the remote machine, executing the process and getting back the result. By “things it needs” I mean: assembler, linker, libc, libgcc and some other libraries like libm, libgmp, libstdc++, libz, etc. Creating this environment with icecream is dead easy: call “icecc –build-native”. Following is the output I get on my Archlinux box with gcc 4.6.0 as default compiler:

$ icecc --build-native
adding file /usr/bin/gcc
adding file /lib/libc.so.6
adding file /lib/ld-linux-x86-64.so.2
adding file /usr/bin/g++
adding file /usr/bin/as
adding file /usr/lib/libopcodes-2.21.0.20110430.so
adding file /usr/lib/libbfd-2.21.0.20110430.so
adding file /lib/libdl.so.2
adding file /usr/lib/libz.so.1
adding file /usr/bin/cc1=/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.0/cc1
adding file /usr/lib/libcloog-isl.so.1
adding file /usr/lib/libisl.so.6
adding file /usr/lib/libgmp.so.10
adding file /usr/lib/libppl_c.so.4
adding file /usr/lib/libppl.so.9
adding file /usr/lib/libgmpxx.so.4
adding file /usr/lib/libstdc++.so.6
adding file /lib/libm.so.6
adding file /usr/lib/libgcc_s.so.1
adding file /usr/lib/libpwl.so.5
adding file /usr/lib/libmpc.so.2
adding file /usr/lib/libmpfr.so.4
adding file /usr/bin/cc1plus=/usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.0/cc1plus
adding file /usr/lib/gcc/x86_64-unknown-linux-gnu/4.6.0/liblto_plugin.so
adding file /etc/ld.so.conf=/tmp/icecc_ld_so_confPaVA2Q
creating 6b1d2b44080a004a88c0746fe128172e.tar.gz

Note that in the last line it created a .tar.gz file. This is the environment that will be sent to other machines. If you want to use another compiler, you need to create another environment that will be later passed to icecream in the second step.

To create an environment for a compiler that is not the default in your machine, first thing you need is to have it in your PATH, pointing to the icecc binary. Here sometimes I use GCC 4.4 instead of the default compiler, so I’ll use it as an example. In my machine, GCC 4.4 is installed in /usr/bin/gcc-4.4 and icecream is installed in /opt/icecream/bin:

$ which gcc-4.4
/usr/bin/gcc-4.4
$ which icecc
/opt/icecream/bin/icecc

Go to where icecc is installed and make a symlink to icecc with the same name of the compiler you want to use:

$ sudo ln -s icecc gcc-4.4
$ sudo ln -s icecc g++-4.4

Now, tell icecream to create the environment for this compiler:

$ cd /tmp
$ export ICECC_CC=gcc-4.4
$ export ICECC_CXX=g++4.4
$ icecc --build-native

Now your environment is ready. Copy the file generated to somewhere you’ll remember later (you can give it whatever name you like):

$ sudo cp my-environment-built-above.tar.gz /var/icecream/gcc-4-4.4_x86-64.tar.gz

This step will be done only once, as opposed to the second step below that is repeated whenever you compile a new source.

2. Tell icecream which environment to use

When compiling a source code, tell icecream which environment it will send to other hosts. You do this by exporting some env vars:

$ export ICECC_CC=gcc-4.4
$ export ICECC_CXX=g++-4.4
$ export ICECC_VERSION=/var/icecream/gcc-4-4.4_x86-64.tar.gz

Now you can compile your source code as usual, be it calling gcc directly or through makefiles or other build systems. For example:

$ gcc-4.4 helloworld.c -o helloworld

If you manage a handful of machines running icecream, I’d recommend a software we developed at ProFUSION called Picolé.

UPDATE: if you want a recommendation on how to build a cross toolchain, crossdev it is. The steps are the same as above, replacing gcc-4.4 with the name given to your compiler (e.g. arm-elf-gcc-4.6.0)

One thought on “Cross-compiling with icecc/icecream”

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>