Distcc

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

Other languages:
Deutsch • ‎English • ‎español • ‎français • ‎italiano • ‎日本語 • ‎한국어 • ‎polski • ‎русский • ‎Türkçe • ‎中文(中国大陆)‎
Resources

Distcc is a program designed to distribute compiling tasks across a network to participating hosts. It is comprised of a server, distccd, and a client program, distcc. Distcc can work transparently with ccache, Portage, and Automake with a small amount of setup.

When planning on using distcc to help bootstrap a Gentoo installation, make sure to read Using distcc to bootstrap.

インストール

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

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

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

USE flags

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

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

Emerge

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

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

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

Configuration

Service

In order to have distccd started automatically follow the next set of instructions.

OpenRC

Edit /etc/conf.d/distccd and make sure to set the --allow directive to allow only trusted clients. For added security, use the --listen directive to tell the distccd daemon what IP to listen on (for multi-homed systems). More information on distcc security can be found at Distcc security notes.

次の設定例では、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"
Important
重要なことは、 --allow--listen を使用することです。distccd man ページか、もっと詳しくは上記のセキュリティについてのドキュメントをご覧ください。

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

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

systemd

Edit the /etc/systemd/system/distccd.service.d/00gentoo.conf file to add the allowed clients in CIDR format. Matching the example will add all IP addresses in the 192.168.1.xxx range:

FILE /etc/systemd/system/distccd.service.d/00gentoo.confALLOWED_SERVERS の設定
Environment="ALLOWED_SERVERS=192.168.1.0/24"
Note
The name "ALLOWED_SERVERS" here is rather confusing as it refers to the clients that are allowed to connect to the local distccd server. Nevertheless, it is this variable which is used in the distccd service as value for the --allow option – see the /usr/lib/systemd/system/distccd.service file for additional information.

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

root #systemctl daemon-reload

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

root #systemctl enable distccd
root #systemctl start distccd

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

distcc-configコマンドを使用すれば、ホストのリストを設定することができます。

The following is an example list of host definitions. In most cases, variants of lines 1 and 2 suffice. The latter uses the /limit syntax to inform distcc about the maximum amount of jobs to be launched on this node. More information about the syntax used in lines 3 and 4 can be found in the distcc manual page.

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

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

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

例の中の最初の一行目で書かれたホストを使用して、 distcc の環境を設定してみましょう。

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

Distcc also supports a pump mode, by invoking the pump command. This may significantly reduce build time when multiple files are compiled in parallel. It caches preprocessed headers on the server side and, as a result, gets rid of repeated uploading and preprocessing of these header files.

To configure a host for pump mode, add the ,cpp,lzo suffix to the hosts definitions. Pump mode requires both cpp and lzo flags (regardless of the files being C or 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"

Usage

With 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 distcc-pump"
Note
Setting network-sandbox value in the FEATURES variable on the client seems to prevent it from being able to distribute the compilation data to other servers as it blocks network communication. Be sure it is unset (nonexistent) or disabled (-network-sandbox).
Note
Distcc’s pump mode may significantly reduce build time for big packages. Consider the Specifying participating hosts section for more details.

例えば、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 and CXXFLAGS

make.confファイルを編集するとき、CFLAGSCXXFLAGSmarch=nativeを設定してはいけません。これはよく確認してください。marchnativeに設定されていると、distccdは作業を他のマシンにうまく分散しなくなるでしょう。そのかわり、次のコマンドを実行すれば適切な-march=の値を得ることができます。

user $gcc -v -E -x c -march=native -mtune=native - < /dev/null 2>&1 | grep cc1 | perl -pe 's/^.* - //g;'

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

A GCC bug has recently been fixed in the 8.0 dev tree which facilitates a more reliable and succinct mechanism for extrapolating appropriate machine flags. The fix has been backported to the 6 and 7 branches and should be released fairly soon. Some processing is still required and a script can be found in the distccflags repo, or via wget:

Warning
Downloading scripts and executing them without any validation is a security risk. Before executing such scripts, take a good look at what they want to accomplish and refrain from executing it when the content or behavior is not clear and purposeful.
user $chmod +x distccflags
user $./distccflags -march=native

With 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は、コンパイルに使用するコンピュータのネットワークとタイプによって違います。このアーティクルの最初のところで適切な値の見つけ方をすでに書いておきましたのでご参考ください。

To bootstrap

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

Step 1: Configure Portage

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

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

Update the PATH variable in the installation session as well:

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

Step 2: Getting distcc

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

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

Step 3: Setting up distcc

distcc-config --installを実行して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を使用しないようにしているためだと思われます。

Extras

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

Monitoring utilities

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/02distcc

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

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

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

root #distccmon-gui

SSH for communication

Setting up distcc via SSH includes some pitfalls. First, generate an SSH key pair without password setup. Be aware that portage compiles programs as the Portage user (or as root if FEATURES="userpriv" is not set). The home folder of the Portage user is /var/tmp/portage/, which means the keys need to be stored in /var/tmp/portage/.ssh/

root #ssh-keygen -b 2048 -t rsa -f /var/tmp/portage/.ssh/id_rsa

Second, create a section for each host in the SSH configuration file:

FILE /var/tmp/portage/.ssh/configAdd per-host sections
Host test1
    HostName 123.456.789.1
    Port 1234
    User UserName
 
Host test2
    HostName 123.456.789.2
    Port 1234
    User UserName

Send the public key to each compilation node:

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

Also make sure that each host is available in the known_hosts file:

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

Fix the file ownership as follows:

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

To set up the hosts test1 and test2, run:

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

Please note the @ (@ sign), which specifies ssh hosts for distcc.

Finally, tell distcc which SSH binary to use:

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

It is not necessary to run the distccd initscript on the hosts when distcc communicates via SSH.

Testing

To test distcc, write a simple Hello distcc program and run distcc in verbose mode to see if it communicates properly.

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

Next, turn on verbose mode, compile the program using distcc and link the generated object file into an executable:

user $export DISTCC_VERBOSE=1
user $distcc gcc -c main.c -o main.o # or 'pump distcc <...>'
user $gcc main.o -o main
Note
Replace distcc command with pump distcc for use pump mode.

There should be a bunch of output about distcc finding its configuration, selecting the host to connect to, starting to connect to it, and ultimately compile main.c. If the output does not list the desired distcc hosts, check the configuration.

Finally, ensure the compiled program works properly. To test each host, enumerate each compile host in the hosts file.

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

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
Having the right version of gcc as a slot on a server isn’t enough. Portage uses distcc as a replacement for the compiler referenced by the CHOST variable (i.e. x86_64-pc-linux-gnu) and distccd invokes it by exactly same name. The right version of gcc should be a default system’s compiler on all involved compilation hosts.

-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使用しないでください

See the CFLAGS and CXXFLAGS section and Inlining -march=native for distcc for more information.

Get more output from emerge logs

It is possible to obtain more logging by enabling verbose mode. This is accomplished by adding DISTCC_VERBOSE to /etc/portage/bashrc:

FILE /etc/portage/bashrcEnabling verbose logging
export DISTCC_VERBOSE=1

The verbose logging can then be found in /var/tmp/portage/$CATEGORY/$PF/temp/build.log.

Keep in mind that the first distcc invocation visible in build.log isn’t necessary the first distcc call during a build process. For example a build server can get a one-minute backoff period during the configuration stage when some checks are performed using a compiler (distcc sets a backoff period when compilation on a remote server failed, it doesn’t matter whether it failed on local machine or not).

Dig into the /var/tmp/portage/$CATEGORY/$PF/work/ directory to investigate such situations. Find other logs, or call make explicitly from within the working directory.

Another interesting variable to use is DISTCC_SAVE_TEMPS. When set, it saves the standard output/error from a remote compiler which, for Portage builds, results in files in the /var/tmp/portage/$CATEGORY/$PF/temp/ directory.

FILE /etc/portage/bashrcSaving temporary output
export DISTCC_SAVE_TEMPS=1

参考

DistCC Cross-compiling guideには、distccを使ってどのようにあるアーキテクチャから別のアーキテクチャのプラグラムをビルドするかの説明があります。Athlon(i686)を使ってK6-2(i586)のプログラムをビルドしたり、SPARCを使ってPowerPCのプログラムをビルドをするように簡単に行うことができます。

外部の情報


This article 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 Joshua Saddler (nightmorph)
They are listed here as the 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 the history page.