2012年7月14日土曜日

make とシンボリックリンク

make とシンボリックリンクはかなり相性が悪いと思っていて、自分は使用しないようにしている。

理解しておくべき基本的な事柄として、make は依存関係間で日付を比較するときに、シンボリックリンクそのものの時刻ではなくて、リンク先のファイルの日付を参照する。
touchコマンドもシンボリックリンク自体の日付を更新するのではなくて、リンク先のファイルの日付を更新する。

シンボリックリンクによって、コンパイル対象のファイルまたはディレクトリを切り替えている場合には、注意を要する。
リンク先が切り替わったとしても、必ずしも再コンパイルしてくれません。

例えば、 foo.cbar.c という2つのファイルがあったとして、どちらか一方へ、 source.c というシンボリックリンクを貼り、コンパイルする。

Makefile は以下のようだとする。


app: source.c
        gcc -o $@ $^



$ ls
Makefile  bar.c  foo.c
$ ln -s foo.c source.c
$ make
gcc -o app source.c
$ ls
Makefile  app  bar.c  foo.c  source.c
$ ln -sf bar.c source.c 
$ make
make: `app' は更新済みです


最初に、 foo.c へリンクを貼り、makeしています。
次に、 bar.c へリンクを貼り直しています。
この時点でシンボリックリンク source.c の日付は更新されますが、これは make は見ません。
bar.capp を比較し、app の方が新しいため、make は再コンパイルしてくれないわけです。

複数のソースディレクトリがあって、コンパイル対象を切り替えたい(例えば Linux Kernel の arch みたいに)ことはしばしばあるが、シンボリックリンクは使わないほうがよいと思う。

以前のLinux Kernelはmake中に include/asm から include/asm-(ARCH)へシンボリックリンクを張っていたが、今は廃止している。

組み込みのブートローダーとして有名な u-boot はいまだに、arch の選択にシンボリックリンクを張っているが、make の不具合が多いような気がする。
経験的に、defconfig で対象ボードを切り替える前に、いったんmrproper しないと危険です。

0 件のコメント:

コメントを投稿