5
.PHONY: b
c: a
    @touch c
    @echo "Changed"
a: b
b:
    @date +%s > a

サンプルのmakeファイルでmakeを実行すると、最初に実行されたときに「Changed」が出力されます。ただし、「変更済み」は、3回目、5回目などの実行時にのみ出力されます。これは、makeがターゲット「b」のレシピを実行するとaが更新されることを認識していないように見えるためです。

ターゲットとして「a」を使用するルールを空のレシピに変更すると、makeが実行されるたびに「Changed」が出力されます(予想どおり、偽のターゲットは常に「古い」と見なされます)。例えば

a: b ;

Makeは、PHONYターゲットの暗黙的なルール検索をスキップする必要がありますが、「a」はPHONYではありません。「a」の暗黙のルールが見つからない場合、「a」がそのPHONY依存関係「b」によって変更された可能性があると見なさないようにするのは正しいですか?

4

1 に答える 1

2

Makeはコマンドの効果を分析できないため、ルールを正しく整理するのはユーザーの責任です。

少し異なるケースを考えてみましょう。

d: c b
c: a
    @touch c
    @echo "Changed"
a:
b:
    @date +%s > a

これはあなたの例と同じ振る舞いをします。cMakeが「本当に」がに依存していることを知ることを期待できる方法はありませんb。makefileの作成者に問題があります。

今それが書かれるべき方法:

c: a
        @touch c
        @echo "Changed"

.PHONY: a
a:
        @date +%s > a

aルールはファイルを変更しますa(そしてルールPHONYを強制a的に実行するためだけにあります)。@date ...これは、コマンドが変更することをmakeに通知する方法aです。このmakefileは正しく機能します。

あなたの例は、これら2つの中間です。ルールが別のルールのターゲットであるファイルを変更する場合、makefileは適切に編成されておらず、Makeに障害はありません。PHONYはい、Makeは、ルールに依存するターゲットがそのルールの実行時に更新された可能性があると想定できますが、ルールの実行時に任意のターゲットが更新された可能性があると想定することもできます。そして、Makeがそのパラノイドだったとしたら、それはあまり効率的ではないでしょう。

于 2012-10-04T13:29:31.860 に答える