Após minhas tentativas de criar um binhost resultaram uma bagunça completa que eu mesmo não conseguia manter, hora de uma abordagem mais simples: só deixar os hosts utilizarem o emerge como sempre, mas delegar o trabalho pesado de compilar software para uma máquina mais poderosa.

É aí que entra o distcc. Ele pode ser um pouco mais lento que um binhost, mas é muito mais fácil de configurar.

Neste guia, vamos mostrar como configurar um cliente e um servidor Gentoo usando OpenRC e IPv6.

Passo 1: Configurando o Servidor de Build

Primeiro, precisamos preparar a máquina que fará o trabalho pesado.

  1. Instale o software: Execute emerge --ask sys-devel/distcc no seu servidor.

  2. Configure o daemon: Abra o arquivo de configuração com nano /etc/conf.d/distccd. Como já estamos vivendo no futuro, vamos usar endereços IPv6 ULA para nossa rede local.

    Adicione a seguinte linha (eu randomizei o endereço para este exemplo): DISTCCD_OPTS="${DISTCCD_OPTS} --listen fd98:7654:3210:1:abcd:ef01:2345:6789 --allow fd98:7654:3210:1::/64"

  3. Inicie o serviço: Configure o OpenRC para iniciar o serviço no boot e, em seguida, inicie-o imediatamente:

    rc-update add distccd default
    rc-service distccd start
    

Isso é tudo para o servidor! Uma vantagem de usar IPv6 ULA é que, no geral, você não precisa se preocupar com dores de cabeça de firewall.

Passo 2: Configurando o Cliente

Agora, vamos dizer para a sua máquina local começar a descarregar o trabalho.

  1. Instale o distcc: Execute emerge --ask sys-devel/distcc na sua máquina cliente.

  2. Defina o host: Diga ao cliente onde o servidor está localizado: distcc-config --set-hosts "localhost [fd98:7654:3210:1:abcd:ef01:2345:6789]"

  3. Edite o make.conf: Abra o /etc/portage/make.conf e adicione estas linhas:

    FEATURES="distcc"
    MAKEOPTS="-j8"
    

    Nota: Defina o -j8 para o número de CPUs disponíveis no seu servidor de build.

A Armadilha do “Native”: Lidando com as Flags da CPU

Aqui está um erro comum: a flag native não funciona com o distcc. Se o seu cliente tiver uma CPU diferente do servidor, a compilação vai falhar ou travar. Você precisa inserir as flags diretamente para a arquitetura específica da sua CPU.

Eu recomendo usar o app-misc/resolve-march-native para encontrar as configurações corretas. Execute-o e ele lhe dará uma string parecida com esta: -march=znver3 -mshstk --param=l1-cache-line-size=64 --param=l1-cache-size=32 --param=l2-cache-size=512

Pegue esse resultado e adicione-o diretamente ao seu COMMON_FLAGS no 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"

Testando e Monitorando

Pronto para ver se funciona? Tente uma compilação rápida: emerge --oneshot app-arch/tar

Enquanto ela roda, observe seu servidor de build. Você verá um pico enorme no uso da CPU. Se quiser uma forma visual de monitorar o progresso, execute isto como root no servidor: DISTCC_DIR="/var/tmp/portage/.distcc/" distccmon-gnome &

Solução de problemas: Se algo der errado, não entre em pânico. Você pode debugar o cliente executando export DISTCC_VERBOSE=1 antes do seu comando emerge.

A Regra de Ouro das Atualizações

Esta é a parte mais importante. Para evitar incompatibilidade de versões, você deve seguir uma ordem específica de atualização:

  1. Atualize o GCC do cliente primeiro.
  2. Atualize o servidor de build.
  3. Atualize o restante do sistema do cliente.

Para fazer isso com segurança, execute:

emerge --sync
emerge --oneshot sys-apps/portage
emerge --oneshot gcc

Bom emerge, emerging, emergeção, que seja! Com bem menor dor do que manter binhost.