「Distcc」の版間の差分
Kusanaginoturugi (トーク | 投稿記録) ({{Lowercase title}} のマチガイでした...) |
(→トラブルシューティング: 項目を整理) |
||
230行目: | 230行目: | ||
$ journalctl $(which distccd) -e --since "5 min ago" |
$ journalctl $(which distccd) -e --since "5 min ago" |
||
− | |||
− | === code 110 === |
||
− | |||
− | distcc デーモンのプロセスが起動されるユーザーアカウント (デフォルトは nobody) でツールチェインが正しく機能することを確認してください。以下ではユーザー nobody でツールチェインが動作することをテストします。{{ic|/etc/passwd}} で nobody ユーザーのログインを以下のように変更してください: |
||
− | |||
− | {{hc|$ cat /etc/passwd| |
||
− | ... |
||
− | nobody:x:99:99:nobody:/:/bin/bash |
||
− | ... |
||
− | }} |
||
− | |||
− | それからクロスコンパイラのバイナリが存在するディレクトリに cd してからコンパイラの実行を試行します: |
||
− | |||
− | # su nobody |
||
− | $ ./gcc --version |
||
− | bash: ./gcc: Permission denied |
||
− | |||
− | 上記のエラーが発生する場合、[[#他のアーキテクチャ]] に記述されているグループパーミッションの設定を正しく行ったか確認してください。 |
||
− | |||
− | 変更を行った後は {{ic|/etc/passwd}} を元に戻すようにしましょう。 |
||
− | |||
− | もしくは、sudo を使うことで {{ic|/etc/passwd}} でシェルを変更しなくても実行できます: |
||
− | |||
− | # sudo -u nobody gcc --version |
||
===ログレベルを設定する=== |
===ログレベルを設定する=== |
2024年2月9日 (金) 01:50時点における版
Distcc は C, C++, Objective C, Objective C++ のコードのビルドをネットワーク上の複数のマシンに分散させるプログラムです。distcc は常にローカルビルドと同じ結果を生成し、インストールと使用方法がシンプルで、ローカルコンパイルよりもずっと高速です。makepkg などの Arch のビルドツールで使うことができます。
用語
- マスター
- コンパイルを開始して設定済みのスレーブにコンパイルを分散させるコンピューター。
- スレーブ
- distcc デーモンが動いており、マスターからコンパイルリクエストを受け取る。
インストール
クラスタの PC 全てに distcc パッケージをインストールしてください。
他のディストロや、Cygwin を使用する Windows など他の OS を使う場合は、distcc のドキュメント を参照してください。
設定
スレーブ
スレーブの設定は /etc/conf.d/distccd
に保存します。利用できるコマンドラインオプションは distcc(1) に記載されています。最低でも、許可するアドレスの範囲を CIDR 形式で指定してください:
DISTCC_ARGS="--allow 192.168.0.0/24"
アドレスの範囲を CIDR 形式に変換するツールが次のページにあります: CIDR Utility Tool。
コンパイルに参加する全てのスレーブで distccd.service
を起動してください。起動時に distccd.service
を実行させるには、全てのマシンでサービスを有効化してください。
マスター
スタンドアロン
マスターで設定する distcc の最小設定は、利用するスレーブの設定です。環境変数 DISTCC_HOSTS
や $DISTCC_HOSTS
, $DISTCC_DIR/hosts
, ~/.distcc/hosts
, /etc/distcc/hosts
などの設定ファイルでアドレスを指定することで設定できます。
DISTCC_HOSTS
を使ってスレーブのアドレスを設定する例:
$ export DISTCC_HOSTS="192.168.0.3,lzo,cpp 192.168.0.4,lzo,cpp"
hosts
設定ファイルでスレーブのアドレスを設定する例:
~/.distcc/hosts
192.168.0.3,lzo,cpp 192.168.0.4,lzo,cpp
サーバーのアドレスを明示的に指定する代わりに、avahi の zeroconf モードを使うこともできます。このモードを使うにはサーバーアドレスのところに +zeroconf
と記述して、スレーブ側で distcc デーモンを --zeroconf
オプションを使って起動するようにしてください。このオプションは pump モードをサポートしてないので注意してください。
上記の例ではアドレスに以下のオプションを追加しています:
lzo
: TCP と SSH ホスト (スレーブ) で LZO 圧縮を使う。cpp
: ホスト (スレーブ) で distcc-pump モードを使う。サーバーを起動するにはビルドコマンドを pump スクリプトでラッピングする必要があるので注意。
pump モードの説明は次のページにあります: HOW DISTCC-PUMP MODE WORKS と distcc's pump mode: A New Design for Distributed C/C++ Compilation 。
スレーブで distcc-pump モードを使うには、pump スクリプトを使ってコンパイルを開始する必要があります。そうしないとコンパイルは失敗します。
Makepkg
/etc/makepkg.conf
の以下の3つのセクションを編集してください:
- BUILDENV で distcc の前のエクスクラメーションポイントを外して有効にしてください。
- DISTCC_HOSTS 行をアンコメントして、スレーブの IP アドレスとスラッシュ、使用するスレッドの数を追加してください。後ろの IP アドレスとスレッドは空白で区切ります。リストは一番強力なサーバーから非力なサーバーの順で並べます (処理能力)。
- MAKEFLAGS 変数を個々のサーバーの最大スレッド数をすべて合計した数字にしてください。下の例の場合、5+3+3=11 になります。合計数以上を指定した場合、余った論理スレッドは distcc によってブロックされ、下で説明している distccmon-text などの監視ユーティリティでそのように表示されます。
例:
BUILDENV=(distcc fakeroot color !ccache !check) MAKEFLAGS="-j11" DISTCC_HOSTS="192.168.0.2/5 192.168.0.3/3 192.168.0.4/3"
SSH を通して distcc を使いたい場合、セクションの IP アドレスの前に "@" シンボルを追加してください。キーベースの認証をセットアップしていないときは、認証済みのホストのチェックを無視するように DISTCC_SSH 変数を設定してください: DISTCC_SSH="ssh -i"
。
コンパイル
スタンドアロン
distcc の pump モードを使ってソースファイルをコンパイルするには、次のコマンドを使用します:
$ pump distcc g++ -c hello_world.cpp
この場合 pump スクリプトは distcc を実行してから "-c hello_world.cpp" をパラメータとして g++ を呼び出します。
Makefile プロジェクトをコンパイルするには、まずコンパイラによって設定される変数を確認する必要があります。例えば、gzip-1.6 の場合、Makefile の中に次の行を見つけることができます: CC = gcc -std=gnu99
。基本的に CC
は C プロジェクトで使われる変数で、CXX
は C++ プロジェクトで使われる変数です。distcc を使ってプロジェクトをコンパイルするには以下のようにします:
$ wget ftp://ftp.gnu.org/pub/gnu/gzip/gzip-1.6.tar.xz $ tar xf gzip-1.6.tar.xz $ cd gzip-1.6 $ ./configure $ pump make -j2 CC="distcc gcc -std=gnu99"
上記例では distcc の pump モードによって2つのコンパイルスレッドを使って gzip をコンパイルします。-j
の設定については What -j level to use? を見て下さい。
Makepkg
通常通り makepkg でコンパイルしてください。
CMake を使用
次の CMake オプションを使用して、 distcc で CMake ベースのプロジェクトをビルドします。
$ cmake -DCMAKE_C_COMPILER_LAUNCHER=distcc -DCMAKE_CXX_COMPILER_LAUNCHER=distcc ...
進捗を見る
複数の方法で進行状況を確認することができます。
- distccmon-text
- ログファイルを tail で表示する
distccmon-text を実行してコンパイル状況をチェックします:
$ distccmon-text 29291 Preprocess probe_64.c 192.168.0.2[0] 30954 Compile apic_noop.c 192.168.0.2[0] 30932 Preprocess kfifo.c 192.168.0.2[0] 30919 Compile blk-core.c 192.168.0.2[1] 30969 Compile i915_gem_debug.c 192.168.0.2[3] 30444 Compile block_dev.c 192.168.0.3[1] 30904 Compile compat.c 192.168.0.3[2] 30891 Compile hugetlb.c 192.168.0.3[3] 30458 Compile catalog.c 192.168.0.4[0] 30496 Compile ulpqueue.c 192.168.0.4[2] 30506 Compile alloc.c 192.168.0.4[0]
プログラムを持続的に実行させるには、watch を使うか、コマンドに空白と繰り返す待機秒数を加えます:
$ watch distccmon-text
または
$ distccmon-text 2
ジャーナルのログを監視しても良いでしょう:
# journalctl -f -u distccd
distcc で "クロスコンパイル"
X86
現在、x86_64 環境から i686 のパッケージをビルドするのに、distcc でクラスタに作業を分散させる方法は2つ存在します。どちらも理想的とは言いがたいですが、今のところ、この2つの方法しかドキュメントになっていません。
chroot からなのか、ネイティブ環境からのビルドなのかに関係なく各ノードで一度だけ distccd を実行すれば未修正の ARCH パッケージを使用して makepkg が動作するようになるのが理想ですが、現在のところそのような方法はありません。
議論スレッド があるので、自由に参加してください。
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"
ネイティブ環境から makepkg を呼び出す
ネイティブの x86_64 環境に schroot をセットアップしてください。ネイティブの x86_64 環境から makepkg を実行して i686 パッケージのビルドをするには:
$ schroot -p -- makepkg -src
Multilib GCC を使う方法 (非推奨)
/etc/pacman.conf
を編集して [multilib] リポジトリをアンコメントしてください:
[multilib] Include = /etc/pacman.d/mirrorlist
$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-armv5AUR、 distccd-alarm-armv6hAUR、distccd-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 が発行を停止する
distccd.service
をサービスとして起動すると、 avahi-daemon
の動作が停止する場合があります。これは、 avahi-daemon.service
のユニットファイル (ユニットファイルの編集 を参照してください。) を編集し、 [Unit]
セクションの最後に After=distccd.service
を追加することで、 avahi-daemon.service
が distccd.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.