Provided by: icecc_1.2-1_amd64 bug


       icecream - A distributed compile system


       Icecream is a distributed compile system for C and C++.

       Icecream is created by SUSE and is based on ideas and code by distcc. Like distcc it takes
       compile jobs from your build and distributes it to remote  machines  allowing  a  parallel
       build  on  several machines you have got. But unlike distcc Icecream uses a central server
       that schedules the compile jobs to the fastest free server and is as  this  dynamic.  This
       advantage  pays  off  mostly for shared computers, if you are the only user on X machines,
       you have full control over them anyway.


       You need:

       · One machine that runs the scheduler (icecc-scheduler -d)

       · Many machines that run the daemon (iceccd -d)

       If you want to compile using icecream, make sure $prefix/lib/icecc/bin is the first  entry
       in  your path, e.g. type export PATH=/usr/lib/icecc/bin:$PATH (Hint: put this in ~/.bashrc
       or /etc/profile to not have to type it in everytime)

       Then you just compile with make -j num, where num is  the  amount  of  jobs  you  want  to
       compile  in  parallel.   Do not exaggerate. Too large numbers can overload your machine or
       the compile cluster and make the build in fact slower.


              Never use icecream in untrusted environments. Run the daemons and the scheduler  as
              unpriviliged  user  in  such  networks if you have to! But you will have to rely on
              homogeneous networks then (see below).

       If you want an overview of your icecream compile cluster, or if you just want funny stats,
       you might want to run icemon.


       If  you  are  running  icecream  daemons in the same icecream network but on machines with
       incompatible compiler versions, icecream needs to send your build  environment  to  remote
       machines (note: they all must be running as root if compiled without libcap-ng support. In
       the future icecream might gain the ability to know when machines cannot accept a different
       environment, but for now it is all or nothing).

       Under  normal  circumstances  this  is handled transparently by the icecream daemon, which
       will prepare a tarball with the environment when needed.  This is the recommended way,  as
       the daemon will also automatically update the tarball whenever your compiler changes.

       If  you  want  to  handle  this  manually for some reason, you have to tell icecream which
       environment you are using. Use icecc --build-native to create an archive  file  containing
       all  the  files  necessary  to setup the compiler environment. The file will have a random
       unique name  like  ddaea39ca1a7c88522b185eca04da2d8.tar.bz2  per  default.  Rename  it  to
       something   more   expressive   for   your   convenience,   e.g.  i386-3.3.1.tar.bz2.  Set
       ICECC_VERSION=filename_of_archive_containing_your_environment  in  the  shell  environment
       where  you  start  the  compile jobs and the file will be transferred to the daemons where
       your compile jobs run and installed to a chroot environment for executing the compile jobs
       in  the  environment  fitting  to  the  environment  of the client. This requires that the
       icecream daemon runs as root.


       SUSE got quite some good machines not having a processor from Intel or AMD, so icecream is
       pretty  good  in  using  cross-compiler environments similar to the above way of spreading
       compilers.       There       the       ICECC_VERSION       variable       looks       like
       <native_filename>(,<platform>:<cross_compiler_filename>)*,    for   example   like   this:

       How to package such a cross compiler is pretty straightforward if you look what is  inside
       the tarballs generated by icecc --build-native.


       When  building  for embedded targets like ARM often you will have a toolchain that runs on
       your host and produces code for the target. In these situations you can exploit the  power
       of icecream as well.

       Create  symlinks  from  where  icecc  is  to  the  name  of  your  cross  compilers  (e.g.
       arm-linux-g++ and arm-linux-gcc), make sure that these symlinks are in the path and before
       the  path of your toolchain, with $ICECC_CC and $ICECC_CXX you need to tell icecream which
       compilers to use for preprocessing and local compiling. e.g. set it to ICECC_CC=arm-linux-
       gcc and ICECC_CXX=arm-linux-g++.

       As the next step you need to create a .tar.bz2 of your cross compiler, check the result of
       build-native to see what needs to be present.

       Finally one needs to set ICECC_VERSION and point it to  the  .tar.bz2  you  have  created.
       When you start compiling your toolchain will be used.


              With ICECC_VERSION you point out on which platforms your toolchain runs, you do not
              indicate for which target code will be generated.


       When working with toolchains for multiple targets, icecream can be configured  to  support
       multiple toolchains in the same environment.

       Multiple  toolchains  can  be configured by appending =<target> to the tarball filename in
       the ICECC_VERSION variable. Where the <target> is the cross  compiler  prefix.  There  the
       ICECC_VERSION               variable              will              look              like

       Below   an   example   of   how   to   configure   icecream   to   use   two   toolchains,
       /work/toolchain1/bin/arm-eabi-[gcc,g++]         and        /work/toolchain2/bin/arm-linux-
       androideabi-[gcc,g++], for the same host architecture:

       · Create symbolic links with the cross compilers names (e.g. arm-eabi-[gcc,g++]  and  arm-
         linux-androideabi-[gcc,g++])  pointing  to  where  the  icecc binary is. Make sure these
         symbolic links are in the $PATH and before the path of the toolchains.

       · Create a tarball file for each toolchain  that  you  want  to  use  with  icecream.  The
         icecc-create-env  script  can be used to create the tarball file for each toolchain, for
         example:     icecc-create-env     /work/toolchain1/bin/arm-eabi-gcc     icecc-create-env

       · Set  ICECC_VERSION to point to the native tarball file and for each tarball file created
         to   the    toolchains    (e.g    ICECC_VERSION=/work/i386-native.tar.gz,/work/arm-eabi-

       With these steps the icecrem  will  use  /work/arm-eabi-toolchain1.tar.gz  file  to  cross
       compilers   with   the   prefix   arm-eabi   (e.g.  arm-eabi-gcc  and  arm-eabi-g++),  use
       /work/arm-linux-androideabi-toolchain2.tar.gz file to  cross  compilers  with  the  prefix
       arm-linux-androideabi  (e.g.  arm-linux-androideabi-gcc and arm-linux-androideabi-g++) and
       use /work/i386-native.tar.gz file to compilers without prefix, the native compilers.


       The easiest way to use ccache with icecream is to set CCACHE_PREFIX to icecc  (the  actual
       icecream client wrapper)

       export CCACHE_PREFIX=icecc

       This  will make ccache prefix any compilation command it needs to do with icecc, making it
       use icecream for the compilation (but not for preprocessing alone).

       To actually use ccache, the mechanism is the same like with using icecream  alone.   Since
       ccache does not provide any symlinks in /opt/ccache/bin, you can create them manually:

       mkdir /opt/ccache/bin
       ln -s /usr/bin/ccache /opt/ccache/bin/gcc
       ln -s /usr/bin/ccache /opt/ccache/bin/g++

       And then compile with

       export PATH=/opt/ccache/bin:$PATH

       Note  however  that ccache is not really worth the trouble if you are not recompiling your
       project three times a day from scratch (it adds  quite  some  overhead  in  comparing  the
       preprocessor  output  and  uses quite some disc space and I found a cache hit of 18% a bit
       too few, so I disabled it again).


       You can use the environment variable ICECC_DEBUG to control if icecream gives debug output
       or  not. Set it to debug to get debug output. The other possible values are error, warning
       and info (the -v option for daemon and scheduler raise the level per  -v  on  the  command
       line - so use -vvv for full debug).


       It  is  possible  that compilation on some hosts fails because they are too old (typically
       the kernel on the remote host is too old for the  glibc  from  the  local  host).   Recent
       icecream  versions  should automatically detect this and avoid such hosts when compilation
       would fail. If some hosts are running old icecream versions and  it  is  not  possible  to
       upgrade them for some reason, use



       Numbers of my test case (some STL C++ genetic algorithm)

       · g++ on my machine: 1.6s

       · g++ on fast machine: 1.1s

       · icecream using my machine as remote machine: 1.9s

       · icecream using fast machine: 1.8s

       The  icecream  overhead  is  quite  huge  as  you  might  notice,  but the compiler cannot
       interleave preprocessing with compilation and the file needs to be read/written once  more
       and in between the file is transferred.

       But  even if the other computer is faster, using g++ on my local machine is faster. If you
       are (for whatever reason) alone in your network at some point, you lose all advantages  of
       distributed  compiling and only add the overhead. So icecream got a special case for local
       compilations (the same special meaning that  localhost  got  within  $DISTCC_HOSTS).  This
       makes  compiling  on my machine using icecream down to 1.7s (the overhead is actually less
       than 0.1s in average).

       As the scheduler is aware of that meaning, it will prefer your own computer if it is  free
       and got not less than 70% of the fastest available computer.

       Keep  in mind, that this affects only the first compile job, the second one is distributed
       anyway. So if I had to compile two of my files, I would get

       · g++ -j1 on my machine: 3.2s

       · g++ -j1 on the fast machine: 2.2s

       · using icecream -j2 on my machine: max(1.7,1.8)=1.8s

       · (using icecream -j2 on the other machine: max(1.1,1.8)=1.8s)

       The math is a bit tricky and depends a  lot  on  the  current  state  of  the  compilation
       network, but make sure you are not blindly assuming make -j2 halves your compilation time.


       In  most  requirements  icecream  is not special, e.g. it does not matter what distributed
       compile system you use, you will not have fun if your nodes  are  connected  through  than
       less or equal to 10MBit. Note that icecream compresses input and output files (using lzo),
       so you can calc with ~1MBit per compile job -  i.e.  more  than  make  -j10  will  not  be
       possible without delays.

       Remember  that more machines are only good if you can use massive parallelization, but you
       will for sure get the best result if your submitting machine (the one you called  g++  on)
       will  be fast enough to feed the others.  Especially if your project consists of many easy
       to compile files, the preprocessing and file I/O will  be  job  enough  to  need  a  quick

       The  scheduler will try to give you the fastest machines available, so even if you add old
       machines, they will be used only in exceptional situations, but still  you  can  have  bad
       luck  -  the scheduler does not know how long a job will take before it started. So if you
       have 3 machines and two quick to compile and one long to compile source file, you are  not
       safe from a choice where everyone has to wait on the slow machine. Keep that in mind.


       A short overview of the ports icecream requires:

       · TCP/10245 on the daemon computers (required)

       · TCP/8765 for the the scheduler computer (required)

       · TCP/8766 for the telnet interface to the scheduler (optional)

       · UDP/8765 for broadcast to find the scheduler (optional)

       If the monitor cannot find the scheduler, use ICECC_SCHEDULER=host icemon.


       icecc-scheduler(1), iceccd(1), icemon(1)


       Stephan Kulow <>

       Michael Matz <>

       Cornelius Schumacher <>

       ...and various other contributors.

                                         April 21th, 2005                             icecream(7)