アーカイブとビルド

Cygwinでのbjamの挙動が変だったので調査しました。
どうもCygwinのbjam(BBv1)でライブラリをビルドし、それをリンクする実行ファイルがあった場合、ライブラリのソースが一切変更されていなくても常にビルドされてしまいます。
これだと、Hamigaki.Bjamのようにコンパイルに時間がかかるライブラリでつらいので調査したわけです。


調査の結果、

  1. アーカイブ(スタティックライブラリ)のメンバが必ずmissingになる(見つからないので常にビルド)
  2. アーカイブのメンバは実際にアーカイブファイルをパースして、中にあるファイルの更新時間を確認するようになっている
  3. アーカイブファイルをパースが上手く動いていない

といったことが判明し、パースを行っているfile_archscan()を調べたところ、lseek()に失敗しているのが原因だと分かりました。


straceで確認すると、lseekの第三引数whenceの値が壊れていました。
lseek()のプロトタイプはこうです。

off_t lseek(int fildes, off_t offset, int whence);

ここで問題になるのはoff_tで、Cygwinでは64ビットです。
おそらくこれが32ビットで渡っているのだろうと思い確認したところ、案の定unistd.hがインクルードされておらず、プロトタイプなしで呼ばれていました。
適当な位置でunistd.hをインクルードするよう修正したところ、アーカイブのパースが上手く動くようになり、無駄なリビルドもなくなりました。


なお、このアーカイブのパース処理はBBv2では使っていないようです。
バグ報告すべきか微妙ですね、、、。