GNU makeの実行プロセスについて

GNU makeの実行プロセスについて

私は以下を持っていますMakefile

$ cat Makefile
all: foo

foo: bar
        @true

bar: file.txt
        touch file.txt

file.txt:
        @echo 'Created file.txt'

run:
        @echo 'Target without dependency.'
$

を実行すると、すでに存在していてもmake常にtouch file.txt実行されます。なぜこれが起こるのですか?bar依存関係が満たされている場合(つまり、存在する場合)、ターゲットが実行されるとは予想されませんfile.txt。また、makeデフォルトでは、例で指定された最初のターゲットを正しく選択していますか?Makefileall

答え1

まず、makeはコマンドが実行する操作には興味がありません。コマンドが実行する操作にのみ興味があります。ただそれらをシェルに渡します。

第二に、barファイルを作成したことがfile.txtないのでいつもnewerよりbarルールbar: file.txtが一致し、touch file.txtコマンドが実行されます。

当然、 を対象とするfile.txtルールに触れたり作成する必要があります。file.txt

また、makeがデフォルトでMakefileの最初のターゲット(例ではallと呼ばれる)を選択することは正しいですか?

はい。

答え2

Makefile非標準機能を使用していないため、あなたの質問はGNU makeに限定されません。

  • makefileの最初の一般的なターゲットは次のとおりです。みんな、いわゆる基本対象となります。

  • "all"名前付きファイルがファイルシステムに存在せず、makefileがファイルを生成しないと仮定しているため、これはall常に役に立たないと見なされる疑似ターゲットと見なすことができます。

  • allまた、foomakefileによって生成されないため、常に使用されていないと見なされます。

  • foomakefile の観点から「生成」されるbar時点でダミーコマンドが実行されます。ただし、名前のない.soも常に役に立たないと見なされます。footruefoofoo

  • barmakefileの観点から「生成」されるfile.txt時点と時刻に応じてコマンドが実行されます。これにより、ファイルが存在する場合、そのファイルは最新の状態になり、現在よりも若くないため、そのファイルは使用されなくなります。bartouch file.txtfile.txtbarbarfile.txtbarfile.txt

  • 最新のコマンドをfile.txtコマンドにすることはecho何の影響もありませんが、file.txtすべてのmake実装は特別な日付を想定しているためどんな文書よりも若い(ターゲットファイルの実際の存在やタイムスタンプを確認せずに)これにより、ターゲットコマンドを実行した後に実行が失敗しませんmake

file.txtしたがって、あなたのmakefileはルールに従って作成または再作成されませんfile.txt

一方、あなたのmakefile作品は予想される処理時間file.txtに比べて最新バージョンではありません。これによって異なる場合があります。barbarbarfile.txt

私はそれがどのように機能するかを理解するために、より簡単なmakefileで始めることを提案しますmake

関連情報