This is Gentoo's testing wiki. It is a non-operational environment and its textual content is outdated.
Please visit our production wiki at https://wiki.gentoo.org
Distcc
Distccはネットワーク上のホストで分散コンパイルを行うためのプログラムで、サーバー側であるdistccdとクライアント側であるdistccで構成されています。またccache、Portage、Automakeとの連携もちょっとしたセットアップで可能となります。
Gentooのインストールにdistccを使いたい場合は、ブートストラップに使うを参照してください。
インストール
distccを構築する前に、まずは使用するすべてのホストにsys-devel/distcc パッケージが導入されているかどうか確認しましょう。
全てのホストで必要なこと
distccを使用するには、ネットワークのすべてのコンピュータのGCCが同じバージョンでなければいけません。例を挙げますと、3.3.x(xは任意の数字)を混在させるのは問題ありませんが、3.3.xと3.2.xを混在させた場合はコンパイルエラーや実行時エラーが起きるかもしれません。
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
sys-devel/distccは分散コンパイルに使う全てのホストにインストールしてください。
設定
サービス
distccdを自動的に起動するためには、次の方法に従ってください。
OpenRC
/etc/conf.d/distccd を編集して --allow
ディレクティブに信頼できるクライアントがセットされいるかどうかを確認してください。例えば multi-homded システムを採用しているなどのように、さらにセキュリティを高めるには --listen
ディレクティブで distccd デーモンにどのIPを受け付けるのかを知らせください。distcc のセキュリティについてもっと詳しく知りたいならば、Distcc security notes を参照してください。
次の設定例では、192.168.0.4
と192.168.0.5
で実行されている distcc クライアントは、ローカルで実行されている distccd サーバへの接続が許されます:
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"
重要なことは、
--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アドレスを追加する例をあげますと:
Environment="ALLOWED_SERVERS=192.168.1.0/24"
ここで使われている "ALLOWED_SERVERS" という名前はいささか混乱を招きます。なぜなら、それはローカルの distccd サーバに接続を許されているクライアント(複数)を指し示しているからです。この変数は、 distccd サービスで使用される
--allow
オプションに引き渡されます。– さらなる情報については /usr/lib/systemd/system/distccd.service ファイルを参照してください。このような変更した後は、ユニット・ファイルをリロードしましょう。
root #
systemctl daemon-reload
distccdの自動起動を有効にして、サービスを開始します:
root #
systemctl enable distccd
root #
systemctl start distccd
参加するホストを記述する
distcc-configコマンドを使用すれば、ホストのリストを設定することができます。
ホストのリストの書き方の一例を下に記します。ほとんどのケースでは、1行目と2行目の書き方で十分でしょう。
2行目の書き方のように/limit
シンタックスを使えば、distccにこのノードで最大いくつのジョブを起動できるかを知らせることができます。distcc マニュアルページ では、3行目や4行目のような書き方の詳しい説明が載っています。
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は、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"
使い方
Portageで使用する
Portage が distcc を利用できるように設定するのは簡単です。 distcc feature を有効にして、同時にビルドに参加するジョブ数を設定する変数があるのですがこれに適当な数をいれてやるだけです (この数に従って distcc はビルドするリソースの量を増やします)。
下に示したように、MAKEOPTS変数とFEATURES変数を設定してください。
一般的な戦略としては、
N
の値を「トータルの」(ローカルとリモートの)CPUコアの個数の2倍 + 1に設定し、M
の値を「ローカルの」CPUコアの個数に設定します。
MAKEOPTS変数で-lM
を使用すると過剰なタスクが起動されてしまうのを防ぐことができます。例えば、distccクラスタホストのいくつかが利用できなくなった時(他のシステムでの並列ジョブの量が増加した場合)や、ebuild でリモートビルドを禁止している時(gccなど)です。この仕組みは、システム負荷が M
値以上になった時に、それ以上のジョブの追加を拒否することによって行われます。
# NとMを計算した正しい値に置き換えてください MAKEOPTS="-jN -lM" FEATURES="distcc distcc-pump"
network-sandbox
値をクライアントの FEATURES 変数にセットすると、ネットワーク通信がブロックされるため、コンパイルデータを他のサーバーへ配布することができなくなるようです。必ずこの値を設定しないでおく(存在しないようにする)か、または無効化(-network-sandbox
)するようにしてください。Distccのpumpモードは大きいパッケージのビルド時間を大幅に削減するでしょう。詳細については、 参加するホストを記述する 節をご覧ください。
例えば、4コアPCのホスト2台と2コアPCのローカルがあったと仮定しましょう。すると MAKEOPTS 変数は次のようになります。
# 4コアのリモートホスト2台 = 8 コアのリモート # 2コアのローカルホスト1台 = 2 コアのローカル # コアの総数は、10 なので、 N = 2*10+1 と M=2 MAKEOPTS="-j21 -l2"
CFLAGS と CXXFLAGS
make.confファイルを編集するとき、CFLAGSやCXXFLAGS変数でmarch=native
を設定してはいけません。これはよく確認してください。march
がnative
に設定されていると、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 をご覧ください。
GCCのバグは、適切なマシンフラグを推定するためのより信頼性が高く簡潔なメカニズムを促進する8.0 devツリーにて最近修正されました。この修正は 6 および 7 ブランチにバックポートされており、かなり近いうちにリリースされるはずです。それでもいくつかの処理はまだ必要であり、スクリプトは distccflags repo あるいは wgetで見つけることができます:
スクリプトをなにも検証せずにダウンロードし実行することはセキュリティーリスクになります。こういったスクリプトを実行する前には、それがなにをしようとしているかよく確認し、内容・振舞いが不明なものや目的に沿わないものは実行しないようにしてください。
user $
chmod +x distccflags
user $
./distccflags -march=native
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
は、コンパイルに使用するコンピュータのネットワークとタイプによって違います。このアーティクルの最初のところで適切な値の見つけ方をすでに書いておきましたのでご参考ください。
ブートストラップに使う
distccをブートストラップに使う(たとえば、システムの残りをインストールする前にワーキングツールチェーンをビルドする)には、いくつか手間をかける必要があります。
Step 1: Portage の設定
Gentoo Linux LiveCDで新しくマシンを立ち上げてinstallation instructionsに従ってください。さらに、ブートストラップについての情報もGentoo FAQにありますので参考にしましょう。その次にdsitccを使用して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 --installを実行してdistccをセットアップしましょう。例中のhost#
には実際のIPアドレスやホスト名を入れてください。
root #
/usr/bin/distcc-config --set-hosts "localhost host1 host2 host3 ..."
これでdistccはブートストラップ用に新しく設定されました。以降はインストレーションの手順に従ってください。emerge @systemの後にemerge distccを実行するのをお忘れなく。これは、すべての必要な依存関係のあるパッケージがインストールされているのかを確認するために行います。
ブートストラップと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
もし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 通信
SSH経由のdistccをセットアップする場合、いくつかの落とし穴があります。まず、SSHの鍵ペアをパスワードをセットアップせずに生成してください。portageはプログラムをPortageユーザー(または、 FEATURES="userpriv"
がセットされていない場合にはroot)としてコンパイルすることに注意してください。Portageユーザーのホームフォルダーは /var/tmp/portage/ であり、これは鍵を /var/tmp/portage/.ssh/ に保存しておく必要があることを意味します。
root #
ssh-keygen -b 2048 -t rsa -f /var/tmp/portage/.ssh/id_rsa
次に、SSH設定ファイルに各ホスト用のセクションを作成します:
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/
test1
と test2
というホストをセットアップするには、以下を実行します:
root #
/usr/bin/distcc-config --set-hosts "@test1 @test2"
distccにsshホストを指定する、@
(@ マーク)に注意してください。
最後に、distccにどのSSHバイナリを使うか指示します:
DISTCC_SSH="ssh"
distccがSSH経由で通信する場合、ホスト側でdistccdのinitスクリプトを実行しておく必要はありません。
テスト
distccをテストするには、簡単なHello distccプログラムを書いてdistccをverboseモードで実行し、正しく通信できているか確認します。
#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
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ディレクトリに更新してください:
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.confのCCとCXX変数を上記のようにセットしてもよいでしょう。
これを行うことでPortageの振る舞いを明らかに変えてしまい、将来において奇妙な結果を引き起こすことがあるかもしれません。ですので、混在するCHOSTがどうしても避けられないときにのみ行ってください。
サーバー側で正しいバージョンのgccをスロットとしてインストールしているだけでは不十分です。PortageはdistccをCHOST変数(たとえば
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プロセッサの場合、両方のプロセッサのコンパイルしたコードが混在してしまうのです。
次の注意を心に留めておきましょう:
distcc でコンパイルするときには、make.conf の CFLAGS 変数または CXXFLAGS 変数で
-march=native
や -mtune=native
を 使用しないでください。詳細については、 CFLAGS と CXXFLAGS 節 や Inlining -march=native
for distcc を参照してください。
emerge のログからより多くの出力を得る
verboseモードを有効にすることで、より多くのログを取得することができます。これは DISTCC_VERBOSE を /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/ ディレクトリにあるファイルに保存されます。
export DISTCC_SAVE_TEMPS=1
参考
DistCC Cross-compiling guideには、distccを使ってどのようにあるアーキテクチャから別のアーキテクチャのプラグラムをビルドするかの説明があります。Athlon(i686)を使ってK6-2(i586)のプログラムをビルドしたり、SPARCを使ってPowerPCのプログラムをビルドをするように簡単に行うことができます。
外部の情報
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 Joshua Saddler (nightmorph)
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.