私は以下を持っています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
デフォルトでは、例で指定された最初のターゲットを正しく選択していますか?Makefile
all
答え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
また、foo
makefileによって生成されないため、常に使用されていないと見なされます。foo
makefile の観点から「生成」されるbar
時点でダミーコマンドが実行されます。ただし、名前のない.soも常に役に立たないと見なされます。foo
true
foo
foo
bar
makefileの観点から「生成」されるfile.txt
時点と時刻に応じてコマンドが実行されます。これにより、ファイルが存在する場合、そのファイルは最新の状態になり、現在よりも若くないため、そのファイルは使用されなくなります。bar
touch file.txt
file.txt
bar
bar
file.txt
bar
file.txt
最新のコマンドを
file.txt
コマンドにすることはecho
何の影響もありませんが、file.txt
すべてのmake
実装は特別な日付を想定しているためどんな文書よりも若い(ターゲットファイルの実際の存在やタイムスタンプを確認せずに)これにより、ターゲットコマンドを実行した後に実行が失敗しませんmake
。
file.txt
したがって、あなたのmakefileはルールに従って作成または再作成されませんfile.txt
。
一方、あなたのmakefile
作品は予想される処理時間file.txt
に比べて最新バージョンではありません。これによって異なる場合があります。bar
bar
bar
file.txt
私はそれがどのように機能するかを理解するために、より簡単なmakefileで始めることを提案しますmake
。