distcc

提供: ArchWiki
2024年2月9日 (金) 02:24時点におけるKgx (トーク | 投稿記録)による版 (→‎用語: 同期)
ナビゲーションに移動 検索に移動

関連記事

Distcc は C, C++, Objective C, Objective C++ のコードのビルドをネットワーク上の複数のマシンに分散させるプログラムです。distcc は常にローカルビルドと同じ結果を生成し、インストールと使用方法がシンプルで、ローカルコンパイルよりもずっと高速です。makepkg などの Arch のビルドツールで使うことができます。

用語

client
client は、コンパイルを開始するコンピューターです。
volunteer
volunteer は、client から送信されたコンパイル要求を受け入れるコンピューターです。複数の volunteer をセットアップすることも、単一の volunteer をセットアップすることもできます。

インストール

クラスタの PC 全てに distcc パッケージをインストールしてください。

他のディストロや、Cygwin を使用する Windows など他の OS を使う場合は、distcc のドキュメント を参照してください。

設定

動作モード

Distcc は、Plain mode (デフォルト) または Pump モードで実行できます。大まかに言えば、主な違いは、distcc が前処理されたソースを処理する方法にあります。Plain mode では、完全なソースとコンパイラ引数が転送されます。前処理はクライアント上で保持されます。Pump モードでは、前処理とコンパイルの両方が distcc クラスターに分散され、多くの場合、より効率的かつ高速になります。詳細については、distcc(1) を参照してください。

Volunteers

Volunteers の設定は /etc/conf.d/distccd に保存されます。少なくとも、多くの ipv4 プライベートネットワーク範囲をカバーする --allow-private スイッチを追加するか、ipv6 対応ネットワークがある場合は ipv6 CIDR で --allow を使用します。ファイルへのログ記録は、必要に応じてトラブルシューティングにも役立ちます。

DISTCC_ARGS="--allow-private --log-file /tmp/distccd.log"

または、IPv6 アクセスを許可する必要があり、ネットワーク CIDR が /64 である場合:

DISTCC_ARGS="--allow-private --allow aaaa:bbbb:cccc:dddd:eeee:::/64 --log-file /tmp/distccd.log"

マシン上に複数のインターフェイスが存在する場合は、--listen ADDRESS オプションも渡すことを検討してください。他のオプションも定義できます。distccd(1) を参照してください。

参加しているすべての Volunteers の distccd.service起動/有効化 します。

クライアント

makepkg を使用する場合

次のセクションの /etc/makepkg.conf を編集します。

  1. BUILDENV 配列には distcc をアンバンする必要があります。つまり、感嘆符なしでリストする必要があります。
  2. DISTCC_HOSTS 行のコメントを解除し、Volunteers のホスト名または IP アドレスを追加します。必要に応じて、この後にスラッシュと使用するスレッドの最大数を続けます。後続のノードは空白で区切る必要があります。このリストは、最も強力なものから (処理能力) の順に並べる必要があります。
  3. サーバーあたりの最大スレッド数の約 2 倍に相当するように MAKEFLAGS 変数を調整します。以下の例では、2x(9+5+5+3)=44 となります。
ノート: IP アドレスの代わりにホスト名を使用することもできますが、devtools ビルドスクリプトを使用してビルドすることが目的の場合、ビルドルートでの名前解決は現在サポートされていないため、このシナリオでは IP アドレスを使用してください。IP アドレスを使用するもう 1 つの理由は、名前解決のために pi-hole を実行しているネットワーク上です。pi-hole のログには distcc からのすべてのリクエストが記録され、ログに何千もの余分な行がスパム送信されるためです。
警告: -march=native フラグは、CFLAGS および CXXFLAGS 変数では使用できません。distccd は他のマシンに作業を分散しません。

真に汎用的な設定は存在しないことに注意してください。1 つ試してテストし、結果を他の設定と比較します。以下に、一般的な設定をいくつか示します。

Plain mode の例
BUILDENV=(distcc fakeroot color !ccache check !sign)
MAKEFLAGS="-j44"
DISTCC_HOSTS="localhost/9 192.168.10.2/5 192.168.10.3/5 192.168.10.4/3"
Pump mode の例
BUILDENV=(distcc fakeroot color !ccache check !sign)
MAKEFLAGS="-j70"
DISTCC_HOSTS="localhost/9 192.168.10.2,cpp,lzo 192.168.10.3,cpp,lzo 192.168.10.4,cpp,lzo"

ここで注意すべき点がいくつかあります。

  • Pump mode は、一般に、Plain mode よりも、MAKEFLAGS の 値が高い方が良い性能を発揮します。
  • Pump mode では、IPまたはホスト名は、Pump mode が要求するように、リテラル ',cpp,lzo' でサフィックスされます。さらに、この例の localhost はそうなっていません。これは、distcc が 9 つのジョブが定義された localhost をロードし、より積極的に有志にコード生成を分配することを意味します。より大規模なクラスタでは、クラスタへの分散処理を可能にするために、localhost 上のローカルジョブの数をより少なく制限したいと思うかもしれません。また、localhost の接尾辞に,cpp,lzo を使用することもできます。
  • 前述したように、すべての distcc クラスタで効率的に動作する単一の設定はありません/最適な設定の決定は、テストとベンチマークを通じて経験的に導き出されます。

makepkg を使用しない場合

Plain mode の例

クライアント上の distcc の最小設定には、利用可能な Volunteers の設定と PATH の再定義が含まれます。

$ export PATH="/usr/lib/distcc/bin:$PATH"
$ export DISTCC_HOSTS="localhost/9 192.168.10.2/5 192.168.10.3/5 192.168.10.4/3"
Pump mode の例
$ export PATH="/usr/lib/distcc/bin:$PATH"
$ export DISTCC_HOSTS="localhost/9 192.168.10.2,cpp,lzo 192.168.10.3,cpp,lzo 192.168.10.4,cpp,lzo"

コンパイル

makepkg を使用する場合

Plain mode の例

/etc/makepkg.conf が設定されたら、特別な手順は必要ありません。通常どおり makepkg を呼び出すだけです。

Pump mode の例

ユーザーは、makepkg を使用するかシェル上でコンパイルする前に Pump を開始する必要があります。Pump には、正しく設定された一連の DISTCC_HOSTS があることを確認するチェックが含まれているため、最初に偽の DISTCC_HOSTS 行を定義する必要があります。makepkg は、/etc/makepkg.conf で指定された値を使用することに注意してください。

$ export DISTCC_HOSTS="localhost,cpp,lzo"
$ eval $(pump --startup)

ここで、通常どおり makepkg を呼び出します。

終了したら、必要に応じて Pump を停止します:

$ pump --shutdown
ヒント: makepkgpump で呼び出すと、makepkg の終了後にインクルードサーバーが自動的に閉じられます。

makepkg を使用しない場合

Plain mode の例

#makepkg を使用しない場合 で説明されている 2 つの変数をエクスポートした後、コンパイラを呼び出すだけです:

$ make -j44

一部のプログラムでは、適切に動作するために CC 変数または CXX 変数、あるいはその両方を定義する必要がある場合があります:

$ make -j44 CC=distcc CXX=distcc

Pump mode の例

上図のように Pump を始動します。コンパイルは Plain mode の例と変わりません。

CMake を使用する場合

distcc で CMake ベースのプロジェクトをビルドするには、次の CMake オプションを使用します:

$ cmake -DCMAKE_C_COMPILER_LAUNCHER=distcc -DCMAKE_CXX_COMPILER_LAUNCHER=distcc ...

進捗を見る

distcc には、コンパイルステータスをチェックするために使用できる cli モニター distccmon-text が付属しています。

cliモニターは、繰り返しクエリーを待つ秒数に相当するスペースと整数をコマンドに付加することで、連続的に実行できます:

$ distccmon-text 3
29291 Preprocess  probe_64.c                                 192.168.10.2[0]
30954 Compile     apic_noop.c                                192.168.10.2[0]
30932 Preprocess  kfifo.c                                    192.168.10.2[0]
30919 Compile     blk-core.c                                 192.168.10.2[1]
30969 Compile     i915_gem_debug.c                           192.168.10.2[3]
30444 Compile     block_dev.c                                192.168.10.3[1]
30904 Compile     compat.c                                   192.168.10.3[2]
30891 Compile     hugetlb.c                                  192.168.10.3[3]
30458 Compile     catalog.c                                  192.168.10.4[0]
30496 Compile     ulpqueue.c                                 192.168.10.4[2]
30506 Compile     alloc.c                                    192.168.10.4[0]

distcc で "クロスコンパイル"

X86

現在、x86_64 環境から i686 のパッケージをビルドするのに、distcc でクラスタに作業を分散させる方法は2つ存在します。どちらも理想的とは言いがたいですが、今のところ、この2つの方法しかドキュメントになっていません。

chroot からなのか、ネイティブ環境からのビルドなのかに関係なく各ノードで一度だけ distccd を実行すれば未修正の ARCH パッケージを使用して makepkg が動作するようになるのが理想ですが、現在のところそのような方法はありません。

議論スレッド があるので、自由に参加してください。

Chroot を使う方法 (推奨)

ノート: 以下の方法は全てのノードに distccd をインストールして32ビットの chroot も必要なのであまりエレガントな方法とは言えません。

32ビットの chroot を distcc クラスタの各ノードに設定したら、各ノードで2つの distccd インスタンスを別々のポートで実行させます。片方はネイティブの x86_64 環境で実行させ、もう片方は x86 chroot で動かします。makepkg は schroot コマンドを通して実行します。

i686 chroot の DISTCC_HOSTS にポート番号を追加する

以下のように /opt/arch32/etc/makepkg.conf の各ホストにポート番号 (3692) を追加してください:

DISTCC_HOSTS="192.168.1.101/5:3692 192.168.1.102/5:3692 192.168.1.103/3:3692"
ノート: 上記の設定が必要なのはマスターの i686 chroot だけです。マスターとはコンパイルを実行するマシンを示します。
ネイティブ環境から makepkg を呼び出す

ネイティブの x86_64 環境に schroot をセットアップしてください。ネイティブの x86_64 環境から makepkg を実行して i686 パッケージのビルドをするには:

$ schroot -p -- makepkg -src

Multilib GCC を使う方法 (非推奨)

警告: 以下の方法を使ってネイティブの x86_64 環境から i686 の linux パッケージをビルドするとエラーが発生することが報告されています。カーネルパッケージをビルドする場合 chroot を使用する方法を推奨します。

/etc/pacman.conf を編集して [multilib] リポジトリをアンコメントしてください:

[multilib]
Include = /etc/pacman.d/mirrorlist

gccインストールしてください。

$HOME/.makepkg.conf に以下の行を追加するだけで x86_64 で i686 用のパッケージをコンパイルできます:

CARCH="i686"
CHOST="i686-pc-linux-gnu"
CFLAGS="-march=i686 -O2 -pipe -m32"
CXXFLAGS="${CFLAGS}"

次のコマンドで makepkg を呼び出して下さい:

$ linux32 makepkg -src

i686 パッケージをコンパイルし終わった後は $HOME/.makepkg.conf を忘れずに削除または修正してください。

他のアーキテクチャ

Arch Linux ARM

Arch Linux ARM デバイスでビルドをする場合、開発者は公式のプロジェクトツールチェインを使用することを強く推奨しています [1]。手動で管理するかわりに、AUR では4つのツールチェインとシンプルな systemd サービスユニットを提供しています:

スレーブマシンの設定は#スレーブセクションで書かれているのと同じですが、設定ファイルの名前はインストールしたパッケージの名前に合わせる必要があります。例えば /etc/conf.d/distccd-armv7h となります。

それぞれのパッケージには systemd サービスユニットが含まれています (例: distccd-armv7h.service)。

追加ツールチェイン

ツールチェインを入手する方法は複数存在します:

  • EmbToolkit: クロスコンパイルツールチェインを作成するためのツール。ARM と MIPS アーキテクチャをサポートしており、LLVM ベースのツールチェインのビルドをサポートしています。
  • crosstool-ng: EmbToolkit と同じようなツール。EmbToolkit よりも多数のアーキテクチャをサポートしています (詳しくはウェブサイトを参照)。
  • Linaro: ARM 開発用のツールチェインを提供しています。

EmbToolkit にはツールチェインを設定するためのグラフィカルな設定メニュー (make xconfig) が付属しています。

トラブルシューティング

ArchLinux カーネルパッケージをコンパイルするコツ

公式の PKGBUILD (または AUR からの多く)からカーネルをビルドする場合は、ビルドコマンドの一部としてCC=distcc 変数と CXX=distcc 変数を渡すように PKGBUILD を編集する必要があります。

make bzImage modules htmldocs CC=distcc CXX=distcc

これを行わないと、ビルド中に distcc が機能しなくなります。 FS#64275 を参照してください。

chromium をコンパイルするコツ

clang を使用する chromium のコンパイルは、現在 issue#386 の影響を受けています。 バグを回避するには、 [2] に従って PKGBUILD の _flags 配列に以下を追加します。 こちら ブログ:

'clang_use_default_sample_profile=false'
'is_cfi=false'

Journalctl

問題が発生したときは journalctl を使って原因を確認してください:

$ journalctl $(which distccd) -e --since "5 min ago"

ログレベルを設定する

デフォルトでは、distcc は /var/log/messages.log にログを出力します。このログはファイルに直接出力することができます (distccd の man ページで実際に推奨されています)。ログファイルを /tmp を使って RAM 上に配置することも可能です。また、ログファイルに出力されるエラーのログレベルを下げることもできます。接続のエントリよりもエラーメッセージを見たいというときに有用です。LEVEL は標準的な syslog のレベルで設定でき critical, error, warning, notice, info, debug などを指定します。

以下の行を /etc/conf.d/distccd の DISTCC_ARGS に追記してください:

DISTCC_ARGS="--user nobody --allow 192.168.0.0/24 --log-level error --log-file /tmp/distccd.log"

$HOME/.distcc を移動して HDD/SSD の使用量を制限する

デフォルトでは、distcc は $HOME/.distcc を作成して、一時的に情報を保存してノードにコンパイルさせる作業を割り当てます。/tmp などの RAM に .distcc という名前のディレクトリを作成して $HOME の .distcc にソフトリンクします。これで無駄な HDD の読み書きが減ります。特に SSD の場合は効果的です。

$ mv $HOME/.distcc /tmp
$ ln -s /tmp/.distcc $HOME/.distcc

systemd を使って再起動時にこのディレクトリを再作成 (他のファイルと同じように手動で削除されるまでソフトリンクは消えません) します。以下の tmpfile を作成:

/etc/tmpfiles.d/tmpfs-create.conf
d /tmp/.distcc 0755 <username> users -

distccd-alarm の場合

No such file or directory

次のようなエラーは、ユーザが distcc によって提供される distccd サービスを誤って実行しており、 distccd-alarm パッケージ (つまり、distccd-alarm-armv5AURdistccd-alarm-armv6hAURdistccd-alarm-armv7hAUR、 または distccd-alarm-armv8AURです。) によって提供されていないことを示します。

ターゲットアーキテクチャに適したサービスを開始してください。

distcc[25479] (dcc_execvp) ERROR: failed to exec armv7l-unknown-linux-gnueabihf-g++: No such file or directory

distccd.service の起動時に Avahi-daemon が発行を停止する

この記事またはセクションの正確性には問題があります。
理由: This does not fix anything if the user 再起動s the service later. (議論: トーク:Distcc#)

distccd.service をサービスとして起動すると、 avahi-daemon の動作が停止する場合があります。これは、 avahi-daemon.service のユニットファイル (ユニットファイルの編集 を参照してください。) を編集し、 [Unit] セクションの最後に After=distccd.service を追加することで、 avahi-daemon.servicedistccd.service の後に開始されるようにすることで軽減できます。

/etc/systemd/system/avahi-daemon.service
...

[Unit]
Description=Avahi mDNS/DNS-SD Stack
Requires=avahi-daemon.socket
After=distccd.service

...

参照

  • icecreamAUR - An easier to configure fork of distcc.