current 1st make2006年04月02日 08時28分11秒

前回の紹介したメーリングリストは各週のアーカイブのようだ。 cvs-src current の方が最新らしい。cvs-all よりも、cvs-src の方が見やすい。ports には興味無いので。 hackersもついでに。 announce stable も一応。qa にはほとんど流れて来ないみたいだ。stable の方が参考になりそうな気がする。

さて、前回は current の buildworld がうまくいかなかった。まあ、普通に /usr/src からやりたくないのが一番の原因なのだろうが。その後、nullfs、unionfs、jail 等試したが、オブジェクトを置く位置がデバイス自体が mount された本来のパスを参照しにいくので無理だった。例えば、/usr/src/xxx が /usr/obj/mnt/current/usr/src/xxx となるので、ディレクトリが無く失敗するのである。なお、最初の mkdir では、/usr/obj/usr/src/xxx などとやっていたようではあるが。

なぜ、そこまでして一般的な設定を使いたくないのかは、Release と Current の使い分けによる。基本的に Release を使いたいからである。Current は今のところ qemu を通してのみ、使う予定である。残念ながら、もう一つの FreeBSD を入れられる程、常用の機械のディスクは余裕が無いのである。

NetBSD 程までとはいかないが、FreeBSD も buildworld と buildinstall は違う Release でも出来るようになっていると聞いたことがある。情報元は失念。buildworld の最初にツールを作るのが、その一旦でもある。

そこで、cvsup や build{world,kernl} は Release の入っている qemu ホスト側でやり、install は qemu に src や obj をハードディスクとして渡し、qemu 上での build をなるべく避けるためである。qemu は bochs に比べると速いがどうしても、エミュレーションによる遅延は避けられない。また、current-supfile や cvsup が情報を保持する sup ディレクトリを一つの md-device ファイルに置ければいいと思ったのである。


# ls /usr/local/current/
current-obj.md  current-src.md  current-supfile src             sup
# df
/dev/md1           495726   440668   15400    97%    /usr/src
/usr/src           495726   440668   15400    97%    /usr/local/current/src
/dev/md3           495726        4  456064     0%    /usr/obj

/usr/src は mdconfig で mount し、/usr/local/current/src は nullfs で mount する。そのため、/usr/local/current で cvsup をすると、全ての変更は、/usr/local/current のみで行われるのである。これで、少なくとも current 関連は /usr/local/current に収まる。

Release を作るときはそのまま /usr/src に置くなり、何かを mount すれば current と release の入れ換えもすっきりと手早くできる。

さて、/usr/src と /usr/obj の正統派の手順で buildworld 再開である。今までは、root で作業してきたが、なるべく自分のユーザアカウントでやることにした。cvsup や src と obj の中のパーミッションを自分用に変える。


% make buildworld
==> gnu/usr.bin/groff/man (all)
===> gnu/usr.bin/groff/src (all)
===> gnu/usr.bin/groff/src/libs (all)
===> gnu/usr.bin/groff/src/libs/libgroff (all)
make: don't know how to make /mnt/current/src/gnu/usr.bin/groff/src/libs/libgrof
f/../../../../../../contrib/groff/src/libs/libgroff/assert.cpp. Stop
*** Error code 2

Stop in /usr/src/gnu/usr.bin/groff/src/libs.
*** Error code 1

Stop in /usr/src/gnu/usr.bin/groff/src.
*** Error code 1

標準の位置でコンパイルして、このようなエラーが出て動かないとしたら、犯人はこいつしか無い。

% find . -name .depend
...
./gnu/usr.bin/groff/src/utils/pfbtops/.depend
./gnu/usr.bin/groff/src/utils/tfmtodit/.depend
^C
% grep current ./gnu/usr.bin/groff/src/utils/tfmtodit/.depend
...
  /mnt/current/src/gnu/usr.bin/groff/src/utils/tfmtodit/../../../../../../contri
b/groff/src/include/nonposix.h
  tfmtodit: /usr/lib/libc.a /mnt/current/src/gnu/usr.bin/groff/src/utils/tfmtodi
t/../../../src/libs/libgroff/libgroff.a /usr/lib/libm.a /usr/obj/mnt/current/src
/tmp/legacy/usr/lib/libegacy.a

たくさん出て参りました、やはり。しっかり、ここに原因がありました。find . -name .depend | xargs と削除したら、buildworld/buildkernel 成功。

違う位置に生成ファイルを置くのを追求するのは、又の機会とする。

クイズ: さて、以下の二つのコマンドの結果は同じとなる。しかし、前者の方が後者よりも遥かに早い。その理由を述べよ。


% find . -name .depend | xargs rm
% find . -name .depend -exec rm '{}' \;