hideden.hatenablog.com

はてなぶろぐー。URLなげー。

distccを入れたliveCD/USB作成してお手軽に分散コンパイル!

コンパイル遅いからなんとか速くしたい。distccで分散コンパイルすれば速くなるはず。だけど、それだけの為にまわりのPCにLinuxを入れるのも・・・。ってことで、distccを入れたliveCDを作ってみた。

コンパイルだけしてくれればいいので、なるべくコンパクトなものをベースにしたい。Gentooのinstall-x86-minimal-2007.0-r1.isoが58MBとかなりコンパクトなのでこれをベースに使う。emergeが便利なので作業もGentooLinux上で。

$ cd /tmp
  // 適当なmirrorからISOを落とす
$ wget ftp://ftp.ecc.u-tokyo.ac.jp/GENTOO/releases/x86/2007.0/installcd/install-x86-minimal-2007.0-r1.iso
# mount -t iso9660 -o loop /tmp/install-x86-minimal-2007.0-r1.iso /mnt/cdrom
# ls -lh /mnt/cdrom/
合計 51M
-rw-r--r-- 1 root    root   22K 2007-05-08 05:24 Getting_Online.txt
-rw-r--r-- 1 root    root  6.1K 2007-05-08 05:24 README.txt
-rw-r--r-- 1 root    root  6.7M 2007-05-08 05:26 gentoo.efimg
-rwx------ 1 root    root   44M 2007-05-08 05:26 image.squashfs
drwxr-xr-x 2 hideden users 4.0K 2007-05-08 05:24 isolinux
-rw-r--r-- 1 root    root     0 2007-05-08 05:24 livecd

image.squashfsがrootfs。これをカスタマイズするためにまず解凍する。

  // squashfsを作成・解凍するツールをinstall
# emerge squashfs-tools
# cp /mnt/cdrom/image.squashfs /tmp/
# unsquashfs -d /tmp/squashfs-root image.squashfs
# du -h --max-depth 1
 123M    ./squashfs-root

解凍できた。install-minimalにはgcc等のツールが無いので、導入する。ROOTでsquashfsを展開したディレクトリを指定し、そこ以下にInstallされるようにする。CFLAGSやUSEは妙なのが入らないようにまっさらに。(適当)

# CFLAGS="-O2 -pipe" CXXFLAGS="${CFLAGS}" USE="-*" ROOT=/tmp/squashfs-root/ \
   emerge --oneshot --nodeps gcc gcc-config binutils distcc
 // コンパイル終わるまで1〜2時間放置。

 // distcc自動起動設定
# chroot /tmp/squashfs-root/ /bin/bash
# adduser -u 240 -g 2 -d /dev/null -s /bin/false distcc
# rc-update add distccd default
# nano /etc/conf.d/distccd
  DISTCCD_OPTS="${DISTCCD_OPTS} --allow 0.0.0.0/0"
  // どこからでも接続を許可する設定

# exit
  // chroot環境から抜ける

追加をimage.squashfsに反映する。

# mksquashfs /tmp/squashfs-root/ /tmp/image.squashfs -noappend

これで完成。image.squashfsを置き換えてISOを生成すればいいはず。

  // mkisofsをinstall
# emerge cdrtools

# mkdir /tmp/cdrom
# cp -ar /mnt/cdrom/* /tmp/cdrom/
# cp image.squashfs /tmp/cdrom/
# cd /tmp/cdrom
# mkisofs -v -r -J -o ../distcc_livecd.iso -b isolinux/isolinux.bin \
 -c isolinux/boot.cat -no-emul-boot -boot-load-size 4 \
 -boot-info-table .

できたISOは76MB。コンパクトで素敵。CDRに焼いて起動。

boot: gentoo-nofb docache

って感じで起動すればdistccも自動起動DHCPだったらそのままifconfigでIP調べる。docacheは起動後CD-ROMにアクセスしなくてもいいようにメモリ上にキャッシュするためにつけておく。メモリが256MB以下のPCの場合はメモリが不足する可能性があるので、CDROMうるさいし遅いけど我慢する。

でも、CDROMは何かとかさばるし邪魔。そもそも今回分散要員になるX60X61もX41tもCD-ROMドライブが無い。なのでLiveUSBにする。

だが、install-minimalのinitrdはそのままだとLiveUSB化がうまく行かない。vfatでマウントする際に必要なNLSサポート用のドライバがカーネル組み込みではなくカーネルモジュールとして構築されているのに、initrdには入って無いのが原因。手動で入れる。

# mkdir /tmp/initrd
# cd /tmp/initrd

  // initrdを展開
# zcat /mnt/cdrom/isolinux/gentoo.igz | cpio -id

  // nlsをimage.squashfsの中からコピー
# cp -ar /tmp/squashfs-root/lib/modules/2.6.19-gentoo-r5/kernel/fs/nls lib/modules/2.6.19-gentoo-r5/kernel/fs/

  // moduleを自動で読み込むようにする
# nano etc/modules/fs
  nls_cp437
  nls_iso8859-1
    を末尾に追記

  // initrdを再生成
# find ./ | cpio -H newc -o > /tmp/initrd-new
# cd /tmp
# gzip initrd-new
# mv initrd-new.gz gentoo.igz

これでvfatでもマウントできるinitrdができた。あとはこれをsyslinuxで起動するように設定する。
USBメモリをWindowsPCにてFAT32でフォーマットし、syslinuxを入れる。USBメモリは128MBで十分。最近めちゃくちゃ安いからUSBメモリって素敵。

http://www.kernel.org/pub/linux/utils/boot/syslinux/syslinux-3.51.zip をダウンロードし、展開。Windows用バイナリはwin32以下にある。

C:\....> syslinux -ma X:  // X:はUSBメモリのドライブ名

syslinuxを導入したらUSBメモリにLiveCDの中身をコピーする。コピーするファイルは以下。

image.squashfs
livecd

gentoo
gentoo.igz
isolinux.cfg

下3つはisolinux配下にあるものをUSBメモリのrootに。isolinux.cfgは、syslinux.cfgにリネームする。

あとはBIOSUSBメモリからbootすればOK。USBメモリによってうまくbootしない場合がある。fdiskで一度領域を切り直してformatしなおしたりするとうまく行く場合がある。ケースバイケースなのでその辺はgoogleで。


で、あとはこの作成したCD-ROMまたはUSBメモリを余ってるPC全部に突っ込んで起動。ifconfigでIPを調べておく。コンパイルしたいPCでもdistccdを起動し、

# distcc-config --set-hosts 192.168.0.AAA 192.168.0.BBB 192.168.0.CCC localhost

等と設定しておく。自分自身はソースの振り分けとかがあるので一番最後へ。先に指定した方が優先度が高いらしい。速いPC順でもいいかも。メインが遅いPCの場合はlocalhostを加えずにコンパイルは全部外に割り振る事もできる。MAKEOPTSで指定する同時コンパイル数は、CPU合計数 x 2 + 1くらいを指定するのが定石らしい。今回はCore2Duo x 2 + PenM x 1 だったので、5 x 2 + 1で-j11と指定した。

gentooのemerge場合はmake.confでFEATURES="distcc"と指定すれば自動でdistccを使用してくれる。便利。単発で使用したい場合は、

$ DISTCC_HOSTS="192.168.0.xxx 192.168.0.xxx localhost" make -j11 CC=distcc

とかやればいい。distccについてはそこら中で解説されてると思うのでこのくらいで。



imagemagickglibcコンパイルしてみた結果、普通にコンパイル出来た。distccではうまくコンパイルできない物もあるらしいので、失敗した場合は普通にコンパイルしてみるといいかも。そもそも、livecdに追加するパッケージがgcc gcc-config distcc binutilsの4つだけでいいのかどうかは不明。まぁ足りなくてエラー出たらまた後日足せば良いか。いまいちgccまわりには詳しくないので自信が無い。

今回作ったのはgcc-4.1.2。gccのバージョンが違うとコンパイル結果がおかしくなるらしいので、自分のgccバージョンに合わせたのを作成するといいかも。
作成したISOと、initrdはここ。

distcc_livecd.iso
gentoo.igz

もちろん無保証。