distcc.README   [plain text]


distcc 3.1 Xcode integration
Mark Mentovai and Tom Van Lenten
2009 March 13 - 2009 April 15

THE DEAL
--------
As of 3.1.2, Xcode bundles a fork of an older version of distcc,
2.18.5-Apple.1.  Apple distcc has several changes that allow it to integrate
well with Xcode, including Bonjour-based service advertisement, server
capability querying, precompiled header support, and tweaks to handle
some features unique to Apple gcc and how Xcode calls it.

distcc 2.18 is from the 2004 era, and distcc has been improved in the
intervening five years.  Most notably, distcc 3 supports pump mode, which
allows preprocessing to be offloaded to distccd servers instead of requiring
that it always be done locally.

This project attempts to realign Apple distcc (including Apple-specific
changes to distcc 2.18) with the current released version of distcc, 3.1,
which includes pump mode.

BUILD
-----
mkdir distcc.obj
cd distcc.obj
CFLAGS="-g -Wall" sh ../distcc/configure --prefix=/usr
make

Note that the --prefix=/usr is more critical than it may appear.  The prefix
is actually used to locate the distcc_compilers file for --host-info capability
sharing.

To build the full Xcode integration package on non-Macs, add
--enable-xcode-integration to the configure command line.  This allows non-Mac
distccd servers to assist in Xcode-driven Mac builds, provided that the
proper toolchain and SDKs are available.  See the other projects in this
directory (specifically, gcc_42 and cctools) for details.

This reintegration does not support precompiled prefix headers or the
Apple-specific "indirect" modifications to handle precompiled headers.
Ordinary (non-precompiled) prefix header injection is supported.

RUNNING DISTCCD
---------------
This distccd is invoked slightly differently from Apple distccd.  The
USE_XCODE_SELECT_PATH environment variable is no longer used.  distccd built
with Xcode integration will normally be invoked as:

distccd --daemon --zeroconf --allow 0.0.0.0/0

The distccd launch daemon at /System/Library/LaunchDaemons/distccd.plist
should be modified if it is to be used with this version of distccd.  The
USE_XCODE_SELECT_PATH environment variable should be removed and the
--min-disk-free command line argument and its value should be removed (as
they control precompiled prefix header caching).  The --zeroconf and
--allow command line arguments should be added.

To run distccd on a non-Mac for Xcode integration, provide a --system-version
argument to allow Xcode to choose the host.  For example,
--system-version "10.5.6 (9G55, i386)".  Hopefully, in the future, Xcode
will no longer check system version, and this will become unnecessary.

INTEGRATING WITH XCODE
----------------------
Move /usr/bin/distccd and /Deveoper/usr/bin/distcc out of the way, and replace
them with the new versions you've built.  /usr/bin/distccd needs to be
replaced even on systems that will not serve as distccd servers because Xcode
calls "distccd --host-info" to determine what the local capabilities are when
attempting to find suitable distccd servers.  One of the things that Xcode
tries matching is the distccd version.

Provided that your projects do not rely on precompiled prefix headers, you
should now be using the updated version of distcc and distccd.  Projects that
use precompiled prefix headers must turn them off by clearing the
"Precompile Prefix Header" checkbox in Xcode's build settings.  This setting
corresponds to the GCC_PRECOMPILE_PREFIX_HEADER project file setting.  Prefix
header injection is still supported, but the prefix header cannot be
precompiled.

Note that pump mode is not yet enabled at this point.  Read on.

ENABLING PUMP MODE
------------------
Here's where the build speed-ups come in.  Pump mode is enabled by running
a local "include server" for the duration of the build.  The include server
must be started up before the build begins, and shut down when the build is
complete.  The include server is responsible for computing and caching
header dependencies on distcc's behalf, and expressing them to distcc so that
it may distribute headers to distccd servers.  This scheme relieves the
build host of the burden of performing all preprocessing locally.

Pump mode is generally managed by the "pump" script, which expects the
DISTCC_HOSTS environment variable to be set.  In addition, in order to enable
pump mode, each host in the DISTCC_HOSTS list must contain ",lzo,cpp" in its
specification.  This conflicts with Xcode's setting of the DISTCC_HOSTS
environment variable: Xcode does not place ",lzo,cpp".  As a workaround,
place the real distcc binary at /Developer/usr/bin/distcc_real, and put
distcc_xcode.sh at /Developer/usr/bin/distcc.  This shell script wrapper
around distcc attempts to determine if it looks like pump mode is desired,
and if so, it rewrites DISTCC_HOSTS as set by Xcode to add ",lzo,cpp" to
the host specifications.  It may be worthwhile to move /usr/bin/distcc to
/usr/bin/distcc_real and place distcc_xcode.sh at /usr/bin/distcc as well.

Because the include server's lifetime must be scoped exactly to a single
build operation, it currently works best with the "xcodebuild" command-line
tool.  For example, I run:

DISTCC_HOSTS="heinous.local,lzo,cpp/6 selecty.local,lzo,cpp/6 rimz.local,lzo,cpp/4 dome.local,lzo,cpp/4" .../distcc.obj/pump xcodebuild

pump starts up the include server and sets the INCLUDE_SERVER_PORT environment
variable, and then runs xcodebuild.  xcodebuild will rewrite DISTCC_HOSTS in a
way that would disable pump mode, but that's fixed up by the distcc_xcode.sh
shell script.  The build then proceeds with pump mode active, which should
result in a noticeable speed improvement as well as a more responsive local
system.  When xcodebuild exits, pump will stop the include server.

INTEGRATING PUMP MODE INTO XCODE
--------------------------------
For pump-mode integration into Xcode proper, Xcode should behave differently
when pump mode is desired:

 - It should add ,lzo,cpp to each host specification in DISTCC_HOSTS.
 - It should start up the include server by setting DISTCC_HOSTS and running
   "pump --startup" as a build begins.  pump will print some environment
   variables that should be set for the duration of the build.
 - When Xcode runs distcc, distcc will find the INCLUDE_SERVER_PORT environment
   variable and the ,lzo,cpp tags in DISTCC_HOSTS and operate in pump mode.
 - When a build finishes, Xcode should run "pump --shutdown" with the
   environment varaiables provided by "pump --startup" still intact.  pump
   will stop the include server referenced by INCLUDE_SERVER_PID and will clean
   up the include server's directory identified by INCLUDE_SERVER_DIR.