After my attempts to make a binhost resulted in a overcomplex mess that myself could not maintain, time for a more simplified approach: just let the hosts use emerge as usual, but delegate the heavy lifting to a more powerful machine.
Enter distcc. It might be a bit slower than a perfectly tuned binhost, but it is much easier to set up.
In this guide, we will walk through setting up a Gentoo client and server using OpenRC and IPv6. Please, for the love of all saints and martys, learn IPv6, let IPv4 die in peace.
Step 1: Setting Up the Build Server
First, we need to prepare the machine that will do the heavy lifting.
Install the software: Run
emerge --ask sys-devel/distccon your server.Configure the daemon: Open the configuration file with
nano /etc/conf.d/distccd. Since we are living in the future, we are using IPv6 ULA addresses for our local network.Add the following line (I have randomized the address for this example):
DISTCCD_OPTS="${DISTCCD_OPTS} --listen fd98:7654:3210:1:abcd:ef01:2345:6789 --allow fd98:7654:3210:1::/64"Start the service: Tell OpenRC to start the service at boot and then start it immediately:
rc-update add distccd default rc-service distccd start
That is it for the server! One perk of using IPv6 ULA is that you generally don’t have to worry about firewall headaches.
Step 2: Configuring the Client
Now, let’s tell your local machine to start offloading work.
Install distcc: Run
emerge --ask sys-devel/distccon your client machine.Set the host: Tell the client where the server lives:
distcc-config --set-hosts "localhost [fd98:7654:3210:1:abcd:ef01:2345:6789]"Edit make.conf: Open
/etc/portage/make.confand add these lines:FEATURES="distcc" MAKEOPTS="-j8"Note: Set
-j8to the number of CPUs available on your build server.
The “Native” Trap: Handling CPU Flags
Here is a common pitfall: the native flag does not work with distcc. If your client has a different CPU than the server, the build will fail or crash. You must inline the flags for your client’s specific architecture.
I recommend using app-misc/resolve-march-native to find the right settings. Run it, and it will give you a string like this:
-march=znver3 -mshstk --param=l1-cache-line-size=64 --param=l1-cache-size=32 --param=l2-cache-size=512
Take that output and add it directly to your COMMON_FLAGS in make.conf:
COMMON_FLAGS="-O2 -march=znver3 -mshstk --param=l1-cache-line-size=64 --param=l1-cache-size=32 --param=l2-cache-size=512 -pipe"
Testing and Monitoring
Ready to see if it works? Try a quick build:
emerge --oneshot app-arch/tar
While it runs, watch your build server. You should see a massive spike in CPU usage. If you want a visual way to monitor the progress, run this as root on the server:
DISTCC_DIR="/var/tmp/portage/.distcc/" distccmon-gnome &
Troubleshooting: If things go wrong, don’t panic. You can debug the client by running export DISTCC_VERBOSE=1 before your emerge command.
The Golden Rule of Updates
This is the most important part. To avoid version mismatches, you must follow a specific update order:
- Update the client’s GCC first.
- Update the build server.
- Update the client’s rest of the system.
To do this safely, run:
emerge --sync
emerge --oneshot sys-apps/portage
emerge --oneshot gcc
Happy compiling! With a tad less pain than keeping a binhost.