Distcc

From Gentoo Wiki
Jump to:navigation Jump to:search
This page is a translated version of the page Distcc and the translation is 76% complete.
Resources

Distcc はネットワーク上のホストで分散コンパイルを行うためのプログラムです。サーバーの distccd とクライアントの distcc で構成されています。また ccachePortage、Automake との透過的な連携もちょっとしたセットアップで可能となります。

Gentooのインストールにdistccを使いたい場合は、ブートストラップに使うを参照してください。

インストール

distccを構築する前に、まずは使用するすべてのホストにsys-devel/distcc パッケージが導入されているかどうか確認しましょう。

全てのホストで必要なこと

distccを使用するには、ネットワークのすべてのコンピュータのGCCが同じバージョンでなければいけません。例を挙げますと、3.3.x(xは任意の数字)を混在させるのは問題ありませんが、3.3.xと3.2.xを混在させた場合はコンパイルエラーや実行時エラーが起きるかもしれません。

すべてのシステムが同じバージョンのbinutilsを使用しているか確認してください(eselect binutils list).そうでないと,多くのパッケージがテキストリロケーションのような様々なエラーが出てリンクに失敗するでしょう。

USE フラグ

USE flags for sys-devel/distcc Distribute compilation of C code across several machines on a network

gssapi Enable support for net-libs/libgssglue
gtk Add support for x11-libs/gtk+ (The GIMP Toolkit)
hardened Activate default security enhancements for toolchain (gcc, glibc, binutils)
ipv6 Add support for IP version 6
selinux !!internal use only!! Security Enhanced Linux support, this must be set by the selinux profile or breakage will occur
xinetd Add support for the xinetd super-server
zeroconf Support for DNS Service Discovery (DNS-SD)

Emerge

Distccには分散コンパイルしているタスクを監視するグラフィカルモニタが付属しています。gtk USEフラグをセットすると、このユーティリティーを使えるようにできます。

USEフラグの設定が終わったらsys-devel/distccパッケージをインストールします。

root #emerge --ask sys-devel/distcc
Important
sys-devel/distccは分散コンパイルに使う全てのホストにインストールしてください。

設定

サービス

distccdを自動的に起動するためには、次の方法に従ってください。

OpenRC

/etc/conf.d/distccd を編集して --allow ディレクティブに信頼できるクライアントだけが許可されるように設定されいるかどうかを確認してください。さらにセキュリティを高めるには --listen ディレクティブを使ってどのIPを受け付ければ良いのかをdistccdデーモンに知らせください(multi-homed システムを採用している場合)。distcc のセキュリティについての詳細は、Distcc security notes を参照してください。

警告
distccサーバのポートに接続できる人は誰でもdistccdのユーザとして恣意的なコマンドを実行することが出来ます。

次の設定例では、192.168.0.4192.168.0.5で実行されている distcc クライアントは、ローカルで実行されている distccd サーバへの接続が許されます:

FILE /etc/conf.d/distccdある特定のクライアントがdistccに接続できるようにする
DISTCCD_OPTS="--port 3632 --log-level notice --log-file /var/log/distccd.log -N 15 --allow 192.168.0.4 --allow 192.168.0.5"

/var/log 内のファイルにログを出力するときは、そのログを作成して適切なパーミッションを与えてください:

root #touch /var/log/distccd.log
root #chown distcc:root /var/log/distccd.log
Important
重要なことは、 --allow--listen を使用することです。distccd man ページか、もっと詳しくは上記のセキュリティについてのドキュメントをご覧ください。

それでは、分散コンパイルに参加する全てのコンピュータで distccd デーモンを起動しましょう:

root #rc-update add distccd default
root #rc-service distccd start

systemd

/etc/systemd/system/distccd.service.d/00gentoo.conf ファイルを編集して、CIDR フォーマットにて許可するクライアントを追加してください。192.168.1.xxxの範囲にあるすべてのIPアドレスを追加する例をあげますと:

FILE /etc/systemd/system/distccd.service.d/00gentoo.confALLOWED_SERVERS の設定
Environment="ALLOWED_SERVERS=192.168.1.0/24"

Or an example with multiple clients and a manually specified log-level

FILE /etc/systemd/system/distccd.service.d/00gentoo.confSetting ALLOWED_SERVERS
Environment="ALLOWED_SERVERS=127.0.0.1 --allow 192.168.1.0/24 --allow 10.1.1.1/24 --log-level error"
Note
ここで使われている ALLOWED_SERVERS という変数名はいささか混乱を招きます。なぜなら、それはローカルの distccd サーバに接続を許されているクライアント(複数)を指し示しているからです。この変数は、 distccd サービスで使用される --allow オプションに引き渡されます。– さらなる情報については /usr/lib/systemd/system/distccd.service ファイルを参照してください。
Important
OpenRC とは対照的に、/etc/env.d/* に置かれた環境変数は env-update を実行してdistccd サービスを再起動した後でも、systemd では効果がありません。これは、env-update によって生成される /etc/environment.d は systemd ユーザインスタンスからしか source されないからです。そのため、distccd は systemd システムインスタンスとして生成されます。

To set the proper environment variables for distccd, place them into /etc/systemd/system/distccd.service.d/00gentoo.conf. For example,

FILE /etc/systemd/system/distccd.service.d/00gentoo.conf
[Service]
Environment="ALLOWED_SERVERS=192.168.121.0/24"
Environment="DISTCC_VERBOSE=1"
Environment="DISTCC_SAVE_TEMPS=1"
Environment="CCACHE_DIR=/var/cache/ccache"
Warning
The Environment= directive in /etc/systemd/system/distccd.service.d/00gentoo.conf file does not support variable expansion. Environment="PATH=/usr/lib/ccache/bin:$PATH" will be treated as is, therefore will not work as intended.

For workaround, you need to edit distccd.service by running the following command.

root #systemctl edit --full distccd.service

This will open up an editor. Change the line with ExecStart= directive to

CODE Workaround for appending to PATH
ExecStart=/bin/bash -c "PATH=/usr/lib/ccache/bin:$PATH exec /usr/bin/distccd --no-detach --daemon --port 3632 -N 15 --allow $ALLOWED_SERVERS --log-level debug"

Alternatively, you could also write a shell script wrapper for /usr/bin/distccd.

このような変更した後は、ユニット・ファイルをリロードしましょう。

root #systemctl daemon-reload

distccdの自動起動を有効にして、サービスを開始します:

root #systemctl enable distccd
root #systemctl start distccd

参加するホストを記述する

ローカルクライアントで distcc-config コマンドを使用すれば、ホスト (distccd をサービスとして実行しているシステム) のリストを設定することができます。

ホストのリストの書き方の一例を下に記します。ほとんどのケースでは、1行目と2行目の書き方で十分でしょう。 2行目の書き方のように/limitシンタックスを使えば、distccにこのノードで最大いくつのジョブを起動できるかを知らせることができます。distcc マニュアルページ では、3行目や4行目のような書き方の詳しい説明が載っています。

CODE ホスト定義の例
192.168.0.1          192.168.0.2                       192.168.0.3
192.168.0.1/2        192.168.0.2                       192.168.0.3/10
192.168.0.1:4000/2   192.168.0.2/1                     192.168.0.3:3632/4
@192.168.0.1         @192.168.0.2:/usr/bin/distccd     192.168.0.3

ホストをセッティングする方法にはここで挙げたほかにもいくつかやり方ありますので、詳細については、man ページをご覧ください。

ローカルマシンでもコンパイル作業をさせたいのなら、ホストのリストに localhost を追加しましょう。逆に、ローカルマシンにコンパイル作業をさせたくない場合には、リストから外しましょう。遅いマシンで localhost を設定してると、実際すべてのことが遅くなってしまうでしょう。また、最高のパフォーマンスに調整するためには、設定したものをテストするのも忘れないでください。

例の中の最初の一行目で書かれたホストを使用して、distcc の環境を設定してください。

root #/usr/bin/distcc-config --set-hosts "localhost 192.168.0.1 192.168.0.2 192.168.0.3"

Distccは、pumpコマンドを実行することで、pumpモードもサポートします。これは、複数のファイルが並行ビルドされる場合のビルド時間を大幅に減少させます。このモードは、プリプロセス済みのヘッダーをサーバー側にキャッシュし、結果としてこれらのヘッダーファイルが繰り返しアップロード・プリプロセスされないようにします。

ホストをpumpモード用に設定するには、 ,cpp,lzo というサフィックスをホスト定義に加えます。pumpモードは cpp および lzo フラグを(ファイルがCであるかC++であるかに関わらず)必要とします。

root #/usr/bin/distcc-config --set-hosts "192.168.0.1,cpp,lzo 192.168.0.2,cpp,lzo 192.168.0.3,cpp,lzo"

Hosts also need to be in:

FILE /etc/distcc/hostsShould match --set-hosts
192.168.0.1
192.168.0.2
192.168.0.3

Optionally, to set the maximum number of threads used by a host, add a forward slash "/" after each host:

FILE /etc/distcc/hostsSpecify max number of threads
192.168.0.1/8
192.168.0.2/4
192.168.0.3/16

The same applies to the distcc-config command. If the maximum threads number is not specified, it will default to 4.

使い方

Portageで使用する

Portagedistcc を利用できるように設定するのは簡単です。 distcc feature を有効にして、同時にビルドに参加するジョブ数を設定する変数があるのですがこれに適当な数をいれてやるだけです (この数に従って distcc はビルドするリソースの量を増やします)。

下に示したように、MAKEOPTS変数とFEATURES変数を設定してください。

一般的な戦略としては、

  • Nの値を「トータルの」(ローカルとリモートの)CPUコアの個数の2倍 + 1に設定し、
  • Mの値を「ローカルの」CPUコアの個数に設定します。

MAKEOPTS変数で-lMを使用すると過剰なタスクが起動されてしまうのを防ぐことができます。例えば、distccクラスタホストのいくつかが利用できなくなった時(他のシステムでの並列ジョブの量が増加した場合)や、ebuild でリモートビルドを禁止している時(gccなど)です。この仕組みは、システム負荷が M値以上になった時に、それ以上のジョブの追加を拒否することによって行われます。

FILE /etc/portage/make.confMAKEOPTSとFEATURESの設定
# NとMを計算した正しい値に置き換えてください
MAKEOPTS="-jN -lM"
FEATURES="distcc"

例えば、4コアPCのホスト2台と2コアPCのローカルがあったと仮定しましょう。すると MAKEOPTS 変数は次のようになります。

FILE /etc/portage/make.conf4コア2台(リモート)と2コア1台(ローカル)での MAKEOPTS の設定例example for 2 quad-core (remote) and one dual core (local) PC
# 4コアのリモートホスト2台 = 8 コアのリモート
# 2コアのローカルホスト1台 = 2 コアのローカル
# コアの総数は、10 なので、 N = 2*10+1 と M=2
MAKEOPTS="-j21 -l2"

CFLAGS と CXXFLAGS

make.confファイルを編集するとき、CFLAGSCXXFLAGS変数で-march=nativeを設定してはいけません。これはよく確認してください。marchnativeに設定されていると、distccdは作業を他のマシンにうまく分散しなくなるでしょう。そうではなく、正確なプラットフォーム名と、その CPU のために必要な追加のフラグを列挙するべきです。例えば:

FILE /etc/portage/make.confインライン化された *FLAGS
# 最小限のフラグのリストは以下で生成されます:
#   $ diff -U0 <(LANG=C gcc -Q -O2 -march=sandybridge --help=target) <(LANG=C gcc -Q -O2 -march=native --help=target)
COMMON_FLAGS="-march=sandybridge -mtune=sandybridge -maes" # -march=native を使わないで!
CFLAGS="${COMMON_FLAGS}"
CXXFLAGS="${COMMON_FLAGS}"

詳しくは、 Inlining -march=native for distcc をご覧ください。

automake で使用する

これは、場合にもよりますが、Portageのセットアップよりも簡単です。PATH変数のgcc (/usr/bin/)のあるディレクトリよりも先頭に/usr/lib/ditcc/bin/を書き込むだけでよいのです。ただし、ちょっと注意が必要です。もし ccacheをご使用の場合は、ccacheの後にdistccを配置してください:

root #export PATH="/usr/lib/ccache/bin:/usr/lib/distcc/bin:${PATH}"

これをユーザの ~/.bashrc 等のようなファイルに書き込んでおき、ユーザがログインするたびに設定されるようにしておきましょう。 もしくは、 /etc/env.d/ ファイルに書き込んでグローバルに設定するのもよいかもしれません。

何もつけずにmakeを呼び出すより、-jN(Nは整数)をつけましょう。Nは、コンパイルに使用するコンピュータのネットワークとタイプによって違います。このアーティクルの最初のところで適切な値の見つけ方をすでに書いておきましたのでご参考ください。

ccache で使用する

Ccachedistcc と連携させるには、いくつかの前提条件を満たす必要があります:

  • Ccacheローカルで正しくセットアップされている
  • Distcc が使用したいホストで正しくセットアップされている

The following setup will work as follows:

CODE Flow diagram
[client]                                                      [remote]
ccache <miss?> → compile it and save cache files,
<hit?>           also distribute other source code → distccccache <miss?> → compile it, save cache files, return cache file to client
  ↓                                                           <hit?>
use the local cache file                                        ↓
                                                 return local cache file to client
Warning
The following configuration must be done on all desired hosts!

Configure distccd

In order to let the daemon distccd use ccache, it must masquerade the path /usr/bin with /usr/lib/ccache/bin. Furthermore, when it uses ccache, ccache should use the prefix distcc:

FILE /etc/conf.d/distccd
PATH="/usr/lib/ccache/bin:${PATH}"
CCACHE_PREFIX="distcc"

Additionally distccd must be aware of the environment variables DISTCC_DIR and CCACHE_DIR:

Warning
These variables must be set somewhere in /etc/env.d/, otherwise ccache tries to put cache files in ${HOME}/.ccache/, which might result in a COMPILE_ERROR, due to insufficient permissions. To pinpoint this, use the testing example mentioned below and export DISTCC_SAVE_TEMPS="1" as mentioned here. This will provide error logs from the remote site in /tmp/ by default. The logs will look like this: distcc_server_stderr_*.txt. Be aware, that these environment variables cannot be set in /etc/conf.d/distccd, since they will not be read from distccd for some reason.
FILE /etc/env.d/03distcc_ccache
CCACHE_DIR="/var/cache/ccache"
DISTCC_DIR="/var/tmp/portage/.distcc"

Next, update the environment variables:

root #env-update
>>> Regenerating /etc/ld.so.cache...

Finally, restart the daemon distccd to adapt all changes:

root #rc-service distccd restart

Configure ccache

Warning
When using distcc with ccache, it is necessary to prepare the cache directories manually, since the daemon distccd only works with the user distcc for some reason and it cannot create directories within /var/cache/ccache/. It is not sufficient to add this user to the group portage. Also be aware, that the variable cache_dir_levels, defined in ccache.conf, specifies how many subdirectories have to be created. The following example uses the default, which is 2.

First, prepare the cache directories:

root #cd "/var/cache/ccache/"
root #mkdir {a..z} {0..9} tmp
root #for first_level_directory in $(find . -maxdepth 1 -type d -not -name "." -and -not -name "tmp"); do pushd "${first_level_directory}" >/dev/null; mkdir {a..z} {0..9}; popd >/dev/null; done

The second command (mkdir) will create the first level directories from a to z, 0 to 9 and tmp. The following for loop will then look for the first level directories (find . -maxdepth 1 -type d), excluding the current directory . and tmp (-not -name "." -and -not -name "tmp"). It then descends into each of them (pushd), creates the second level directories from a to z and 0 to 9 (mkdir) and goes back to the previous directory (popd), which is /var/cache/ccache/.

Important
The current directory . must be excluded with -not -name ".", otherwise the first pushd command will go to the current directory . and then goes back to whatever directory is currently on the stack via popd. It will navigate through the entire stack until it is empty, creating directories, where each pushd command fails. If this happens, one can search for them using find / -type d -name "0" and remove them with rm --recursive [a-z] [0-9]. It is advised to this manually!

When the preparation is done, every directory - including the directory ccache itself - must be owned by the user distcc:

root #find /var/cache/ccache -type d -exec chown distcc:portage "{}" +

Configure portage

To use emerge with distcc and ccache, make sure, that both features are enabled and that CCACHE_DIR is set in /etc/portage/make.conf:

FILE /etc/portage/make.conf
[...]
FEATURES="distcc ccache"
CCACHE_DIR="/var/cache/ccache"

It might be redundant to set CCACHE_DIR here, since it is already defined in /etc/env.d/03distcc_ccache, mentioned here. But to make absolutely sure, configure it like that.

Testing distcc with ccache manually

リモート

First enable verbose logging by setting --log-level to debug in /etc/conf.d/distccd:

FILE /etc/conf.d/distccd
[...]
DISTCCD_OPTS="${DISTCCD_OPTS} --log-level debug"
[...]

After that, restart the daemon to adapt the changes:

root #rc-service distccd restart

Also check, if there are directories in /var/cache/ccache - including the directory ccache itself - which are not owned by the user distcc and correct their owner permissions:

root #chown -R distcc:portage /var/cache/ccache
クライアント

Make sure, that the following environment variables are present in the current shell:

root #export PATH="/usr/lib/ccache/bin:${PATH}"
root #export CCACHE_DIR="/var/cache/ccache"
root #export DISTCC_DIR="/var/tmp/portage/.distcc"
root #export DISTCC_SAVE_TEMPS="1"
root #export DISTCC_VERBOSE="1"

After that, navigate to a temporary directory within /tmp/ and compile the example mentioned below:

root #cd $(mktemp --directory)
root #distcc gcc -c main.c -o main.o

This will provide a verbose output, while also keeping temporary files receiving from the remote site in /tmp/ by default:

CODE
[...]
distcc[29466] (dcc_cleanup_tempfiles_inner) skip cleanup of /tmp/distcc_9c42f0a6.i
distcc[29466] (dcc_cleanup_tempfiles_inner) skip cleanup of /tmp/distcc_server_stderr_9cc0f0a6.txt
[...]

Any occuring error from the remote site are saved in /tmp/distcc_server_stderr_*.txt.

If the compilation was successful, the following line will be shown.

CODE
[...]
distcc[29466] compile main.c on 192.168.0.4 completed ok
[...]

On the remote site, it will look like this:

CODE
[...]
distccd[13296] (dcc_check_compiler_masq) /usr/lib/ccache/bin/gcc is a safe symlink to /usr/bin/ccache
[...]
distccd[13296] (dcc_job_summary) client: 192.168.0.4:33880 COMPILE_OK exit:0 sig:0 core:0 ret:0 time:20ms gcc main.c

The important part here, is, that any symlink of /usr/lib/ccache/bin/ is a save symlink to /usr/bin/ccache.

Also, on the remote site, there should be the cached file 2beaa22dc2a2873d6869d69411840c-17229.o in /var/cache/ccache/c/0/, assuming, the example with its filename was copied from this wiki article. Generally, one can monitor the ccache size using watch "ccache --show-stats", while compiling.

Testing distcc with ccache using emerge

Check, if necessary environment variables are present for the current shell, see here and that /etc/portage/make.conf was configured properly, see here.

To produce some cached files on the remote site, one can compile small packages like htop and bzip2 on the client:

root #emerge --ask htop bzip2

Future usage

Make sure, that the following environment variables are always set in the desired shell:

CODE
PATH="/usr/lib/ccache/bin:${PATH}"
CCACHE_DIR="/var/cache/ccache"
DISTCC_DIR="/var/tmp/portage/.distcc"

ブートストラップに使う

distccをブートストラップに使う(たとえば、システムの残りをインストールする前にワーキングツールチェーンをビルドする)には、いくつか手間をかける必要があります。

Step 1: Portage の設定

Gentoo Linux LiveCDで新しくマシンを立ち上げてinstallation instructionsに従ってください。さらに、ブートストラップについての情報もGentoo FAQにありますので参考にしましょう。その次にdsitccを使用してPortageを初期設定してください。

FILE /etc/portage/make.confdistccを使用するためのPortageの設定
FEATURES="distcc"
MAKEOPTS="-jN"

インストレーションセッションでPATH変数を次のように更新:

root #export PATH="/usr/lib/ccache/bin:/usr/lib/distcc/bin:${PATH}"

Step 2: distcc をゲット

sys-devel/distccをインストール:

root #USE='-*' emerge --nodeps sys-devel/distcc

Step 3: distcc のセッティング

distcc-configを実行してdistccをセットアップしましょう。例中のhost#には実際のIPアドレスやホスト名を入れてください。

root #/usr/bin/distcc-config --set-hosts "localhost host1 host2 host3 ..."

これでdistccはブートストラップ用に新しく設定されました。以降はインストレーションの手順に従ってください。emerge @systemの後にemerge distccを実行するのをお忘れなく。これは、すべての必要な依存関係のあるパッケージがインストールされているのかを確認するために行います。

Note
ブートストラップとemerge @systemの間、distccが使われていないことを見つけてしまうかもしれません。これはdistccとうまくいかないようなebuildがあり、そのようなebuildはわざとdistccを使用しないようにしているためだと思われます。

付属するツール群

distccアプリケーションには、distcc環境での作業をサポートするための機能やアプリケーションがあります。

監視ユーティリティ

Distccには2つの監視ユーティリティが付属しています。テキストベースの監視ユーティリティは distccmon-text で、必ずビルドされます。最初に実行するときは少々混乱するかもしれませんが、実際とても簡単に使うことができます。パラメータなしで実行したときは、プログラムは1回だけ実行されますが、引数にNを渡すと、N秒ごとに更新が行われます。

user $distccmon-text 10

もうひとつの監視ユーティリティは gtk USE フラグがセットされた時のみ有効になります。これはGTKベースで、X環境で動作し、なかなか良い外見をしています。 Gentooでは、このGUIモニタは混乱を避けるため distccmon-gui にリネームされています(もともとの名前はdistccmon-gnome です)。

user $distccmon-gui

Portageでのdistccの使用をモニタするには:

root #DISTCC_DIR="/var/tmp/portage/.distcc/" distccmon-text 10
root #DISTCC_DIR="/var/tmp/portage/.distcc/" distccmon-gui
Important
もしdistccディレクトリが別の場所にあるなら、それに合わせてDISTCC_DIR変数を変えてください。

DISTCC_DIRを環境変数にセットするための良い方法:

root #echo 'DISTCC_DIR="/var/tmp/portage/.distcc/"' >> /etc/env.d/03distcc_custom
Important
Be aware that DISTCC_DIR must be set somewhere else than /etc/env.d/02distcc, as it gets overwritten everytime, when using distcc-config!. distcc-config --set-env DISTCC_DIR <some_path> does not work.

ここで、環境を更新します:

root #env-update
root #source /etc/profile

最後に、GUIアプリケーションを起動しましょう。

root #distccmon-gui

SSH 通信

SSH経由のdistccをセットアップする場合、いくつかの落とし穴があります。まず、SSHの鍵ペアをパスワードをセットアップせずに生成してください。portageはプログラムをPortageユーザー(または、 FEATURES="userpriv" がセットされていない場合にはroot)としてコンパイルすることに注意してください。Portageユーザーのホームフォルダーは /var/tmp/portage/ であり、これは鍵を /var/tmp/portage/.ssh/ に保存しておく必要があることを意味します。

Warning
Home folder of the Portage user changed in recent versions to /var/lib/portage/home, but this folder cannot be used for distcc via SSH because it is out of the accessible path during compilation. You should then update it:
root #usermod -d /var/tmp/portage portage
root #ssh-keygen -b 2048 -t rsa -f /var/tmp/portage/.ssh/id_rsa

次に、SSH設定ファイルに各ホスト用のセクションを作成します:

FILE /var/tmp/portage/.ssh/confighostごとにセクションを追加する
Host test1
    HostName 123.456.789.1
    Port 1234
    User UserName
 
Host test2
    HostName 123.456.789.2
    Port 1234
    User UserName

公開鍵を各コンパイルノードに送信します:

root #ssh-copy-id -i /var/tmp/portage/.ssh/id_rsa.pub UserName@CompilationNode

また、各ホストが known_hosts ファイルに含まれていることを確認します:

root #ssh-keyscan -t rsa <compilation-node-1> <compilation-node-2> [...] > /var/tmp/portage/.ssh/known_hosts

ファイルの所有者を以下のように修正します:

root #chown -R portage:portage /var/tmp/portage/.ssh/

test1test2 というホストをセットアップするには、以下を実行します:

root #/usr/bin/distcc-config --set-hosts "@test1 @test2"

distccにsshホストを指定する、@ (@ マーク)に注意してください。

最後に、distccにどのSSHバイナリを使うか指示します:

FILE /etc/portage/make.conf
DISTCC_SSH="ssh"

distccがSSH経由で通信する場合、ホスト側でdistccdのinitスクリプトを実行しておく必要はありません。

Reverse SSH

As an alternative to distcc's built-in SSH solution, a compiling server can connect to the distcc client via SSH, redirecting the client's distcc TCP port to the compiling server. There is no need for password-less SSH keys on the client.

user $ssh -R3632:127.0.0.1:3632 root@distcc-client

Note that distcc uses localhost as a literal keyword for special purpose so that 127.0.0.1 has to be used instead. For multiple compiling servers each needs its own port redirection on the client (e.g. 127.0.0.1:4000, 127.0.0.1:4001 etc). Assert that IP addresses and ports are listed in /etc/distcc/hosts on the client.

テスト

distccをテストするには、簡単なHello distccプログラムを書いてdistccをverboseモードで実行し、正しく通信できているか確認します。

FILE main.c
#include <stdio.h>
 
int main() {
    printf("Hello distcc!\n");
    return 0;
}

次に、verboseモードを有効にしてからdistccを使ってプログラムをコンパイルし、生成されたオブジェクトファイルをリンクして実行可能ファイルにします。

user $export DISTCC_VERBOSE=1
user $distcc gcc -c main.c -o main.o # または 'pump distcc <...>'
user $gcc main.o -o main
Note
pumpモードを使用するには、 distcc コマンドを pump distcc に置き換えてください。

distccの設定の探索、接続するホストの選択、接続の開始、そして最後に main.c のコンパイルについて、一連の出力があるはずです。出力の中で使いたいdistccホストがリストされない場合、設定を確認してください。

最後に、コンパイルされたプログラムが正しく動作するか確認してください。ホストそれぞれについてテストするには、hostsファイルで各コンパイルホストを列挙してください。

user $./main
Hello distcc!

トラブルシューティング

distcc をご使用中に問題が発生したときには、このセクションをお読みになれば問題解決の糸口となるかもしれません。

ERROR: failed to open /var/log/distccd.log

2015年1月22日以降、emergeすると /var/log/ に適切な distccd.log ファイルを作るのに失敗します。これは、 distcc ver.3.1-r8 のみに起こることが明らかにされています。このバグは現在修正中ですが(参照:bug #477630)、手作業でそのログファイルを作成し、適切な所有者を設定し、distccデーモンを再起動することで何とかうまく動くようにできます。

root #mkdir -p /var/log/distcc
root #touch /var/log/distcc/distccd.log
root #chown distcc:daemon /var/log/distcc/distccd.log

次に、/etc/conf.d/distccdにあるdistccdコンフィグレーションファイルの/var/logの値を先ほど作成したdistccディレクトリに更新してください:

FILE /etc/conf.d/distccdUpdating log path
DISTCCD_OPTS="--port 3632 --log-level notice --log-file /var/log/distcc/distccd.log -N 15

最後に distccd サービスを再起動します。

root #/etc/init.d/distccd restart

distccをつかえないパッケージもあります

様々なパッケージをインストールしていく中で、分散されない(並列にビルドできない)パッケージがあることに気づくでしょう。これは、そのパッケージのMakefileが並列オペレーションをサポートしていない、あるいはそのebuildのメインテナーが既知の問題があるために並列オペレーションを禁止しているからだと思われます。

時として、distccはパッケージのコンパイルに失敗することもあります。このようなことが起こりましたら、お手数ですが報告してください。

Rust package is known to cause excessive IO utilization as --local-load is ignored and --jobs is usually too high for local build resources. A package.env needs to be provisioned with non-distcc MAKEOPTS values to workaround this behaviour.

GCC のバージョンが混在する場合

もしdistcc環境のホスト間でGCCのバージョンが違っていたら、奇怪な問題が起こるかもしれません。解決法は、すべてのホストが同じバージョンのGCCであることをしっかり確認することです。

最近のPortageのアップデートでは、gccのかわりに${CHOST}-gcc(minus gcc)を使うようになっています。しかしながらこのことは、もしi686マシーンがほかのタイプのマシーン(i386,i586)と混在していた場合には、ビルドが失敗に終わってしまうことになります。この問題に対しては、次の対処をするとよいかもしれません:

root #export CC='gcc' CXX='c++'

/etc/portage/make.confCCCXX変数を上記のようにセットしてもよいでしょう。

Important
これを行うことでPortageの振る舞いを明らかに変えてしまい、将来において奇妙な結果を引き起こすことがあるかもしれません。ですので、混在するCHOSTがどうしても避けられないときにのみ行ってください。
Note
サーバー側で正しいバージョンのgccをスロットとしてインストールしているだけでは不十分です。PortageはdistccCHOST変数(たとえば x86_64-pc-linux-gnu)で参照されるコンパイラーの代わりに使用し、distccdはそれをまったく同じ名前で実行します。正しいバージョンのgccは、すべての関係するコンパイルホストにおいてシステムのデフォルトコンパイラーである必要があります。

-march=native

GCC 4.3.0よりコンパイラは-march=nativeオプションをサポートするようになりました。これは、CPU自動判別と最適化の機能を有効にするものでで、GCCが実行されているプロセッサに対しては有効にしておく価値のあるものです。しかしながら、そのオプションでdistccを使用した場合には、一つ問題が引き起こされます。理由はそれぞれのプロセッサでの最適化されたコードが混在してしまうからです。例を挙げますと、-march=nativeとともにdistccを実行するとき、あるシステムでは AMD Athlon プロセッサで、別のシステムでは Intel Pentiumプロセッサの場合、両方のプロセッサのコンパイルしたコードが混在してしまうのです。

次の注意を心に留めておきましょう:

Warning
distcc でコンパイルするときには、make.confCFLAGS 変数または CXXFLAGS 変数で -march=native-mtune=native使用しないでください

詳細については、 CFLAGS と CXXFLAGS 節Inlining -march=native for distcc を参照してください。

Network is unreachable

Note
When using SSH connection, you may also face the error: ssh: Could not resolve hostname: Temporary failure in name resolution.

Due to network restrictions introduced by the feature network-sandbox, you may run into this issue. Since distcc contradicts with this security feature, you have to disable it:

FILE /etc/portage/make.confDisabling network-sandbox feature
FEATURES="${FEATURES} -network-sandbox"

emerge のログからより多くの出力を得る

verboseモードを有効にすることで、より多くのログを取得することができます。これは DISTCC_VERBOSE/etc/portage/bashrc に追加することによって実現できます。

FILE /etc/portage/bashrc詳細なログを有功にする
export DISTCC_VERBOSE=1

これで、詳細なログが /var/tmp/portage/$CATEGORY/$PF/temp/build.log で見られるようになります。

build.log で見られる最初のdistccの実行は、必ずしもビルドプロセス中の最初のdistccの実行であるとは限らないことを覚えておいてください。たとえば、ビルドサーバーは、コンパイラーを使ったチェックがいくつか実行された場合にconfigurationの段階で1分間のバックオフ期間に入る可能性があります(distccはリモートサーバーでのコンパイルが失敗すると、それがローカルマシンでも失敗したかどうかに関わらずバックオフ期間を設定します)。

こうした状況を調査するには、 /var/tmp/portage/$CATEGORY/$PF/work/ ディレクトリに入ってください。他のログを探すか、あるいは作業ディレクトリの中から明示的にmakeを呼び出します。

もう一つの使うと興味深い変数は DISTCC_SAVE_TEMPS です。設定されている場合、リモートのコンパイラーからの標準出力/エラー出力を保存します。Portageビルドでは、結果は /var/tmp/portage/$CATEGORY/$PF/temp/ ディレクトリにあるファイルに保存されます。

FILE /etc/portage/bashrc一時的な出力の保存
export DISTCC_SAVE_TEMPS=1

ディレクトリ /dev/null/.cache/ccache/tmp を作成できません: ディレクトリではありません

This error can be discovered from the standard error output file in the server if you set DISTCC_SAVE_TEMPS. It only occurs when using distccd with ccache.

Likely, it is because CCACHE_DIR is not properly set, or not passed correctly to distccd. ccache will then default to $HOME/.cache/ccache as its cache folder. However, ccache is run by distccd under user distcc, which is a non-login account. See systemd section and With ccache section for setting CCACHE_DIR.

Portage build failing with errors that are apparently not connected with distcc at all

When builds are failing with errors that do not seem to be connected to distcc, but the build works with FEATURES="-distcc", it has been reported that builds sometimes fail because of DISTCC_VERBOSE=1. Try the build with DISTCC_VERBOSE=0.

参考

  • Distcc/Cross-Compiling — 異なるプロセッサアーキテクチャ間でクロスコンパイルするために distcc をセットアップする方法を示します。

外部の情報


This page is based on a document formerly found on our main website gentoo.org.
The following people contributed to the original document: Lisa Seelye, Mike Gilbert (floppym) , Erwin, Sven Vermeulen (SwifT) , Lars Weiler, Tiemo Kieft, and
They are listed here because wiki history does not allow for any external attribution. If you edit the wiki article, please do not add yourself here; your contributions are recorded on each article's associated history page.