1

次のメイクファイルを検討してください。

foo :
    mkdir foo

foo/a.out : foo a.in
    cp a.in foo/a.out

foo/b.out : foo b.in
    cp b.in foo/b.out

a.inそして、ファイルのみを含むディレクトリから開始して、それと次の対話を行いb.inます。

$ make foo/a.out
mkdir foo
cp a.in foo/a.out

ここまでは順調ですね。

$ make foo/b.out
cp b.in foo/b.out

まだ良いですが、今:

$ make foo/a.out   # a.out should be up to date now!
cp a.in foo/a.out

a.out前提条件がまったく変更されていない場合でも、ターゲットを再構築します。

が作成されるfoo/b.outと、ディレクトリの最終変更時刻fooが更新されるため、「変更」されたものとして取得されるようです。

これを回避する方法はありますか?たとえば、存在する必要があるという点だけにfoo/a.out依存していることを宣言する方法はありますか?内部でファイルを作成しても、時代遅れと見なされることはありませんか?foofoofoofoo

4

3 に答える 3

4

Makeの権威が最近指摘したように

「決してしてはいけないことの 1 つは、単純な前提条件としてディレクトリを使用することです。ファイルシステムがディレクトリの変更時刻を更新するために使用する規則は、make ではうまく機能しません。」

しかし、これはあなたが望むことをすると思います:

foo :
    mkdir foo

foo/a.out : a.in | foo
    cp a.in foo/a.out

foo/b.out : b.in | foo
    cp b.in foo/b.out
于 2013-05-03T01:30:16.733 に答える
2

@Beta の回答は気に入っていますが、移植性はありません。簡単な移植可能な回避策として、ディレクトリの作成時にセンチネル ファイルを作成し、代わりにセンチネル ファイルに依存します。

foo/.dir:
        mkdir -p foo
        touch $@
foo/a.out: a.in foo/.dir
        cp $< $@
foo/b.out: b.in foo/.dir
        cp $< $@

これは、パターン ルールを使用してさらに単純化できます。

foo/%.out: %.in foo/.dir
        cp $< $@
于 2013-05-03T05:51:48.663 に答える