9

GNU makeは、最後に呼び出すことにより、暗黙のルールによって作成された中間ファイルを自動的に削除しますrm filename。ターゲットの1つが実際にディレクトリであった場合、これは明らかに機能しません。次の例を見てください。

.PHONY: all 

all: test.target

%.target: tempdir.% 
  touch $@

tempdir.%:
  mkdir -p $@

make -nアクションプランを明らかにします:

mkdir -p tempdir.test
touch test.target
rm tempdir.test

GNU makeに中間ディレクトリを正しく破棄させることは可能ですか?おそらくに変更することrmによってrm -rf

4

1 に答える 1

7

これを実現する方法はありません。GNU make はコマンド "rm" を出力しますが、実際には内部的に unlink(2) システム コールを直接実行しており、シェル コマンドを呼び出していません。GNU make が実行するコマンドを構成または変更する方法はありません (もちろん、ソース コードを変更する場合を除きます)。

ただし、ターゲットの通常の前提条件としてディレクトリを使用することはうまくいかないことを指摘しておく必要があると思います。GNU make は、最終変更時刻の比較を使用して、ターゲットが最新かどうかを判断しますが、ディレクトリの最終変更時刻は標準規則に従っていません。ディレクトリの TLM は、そのディレクトリ内のファイル (またはサブディレクトリ) が作成、削除、または名前変更されるたびに更新されます。これは、ディレクトリを作成し、それに依存する一連のファイルを作成することを意味します。最初のファイルはビルドされ、タイムスタンプは N です。最後のファイルはビルドされ、タイムスタンプは N+x です。これにより、ディレクトリのタイムスタンプも N+x に設定されます。次に make を実行すると、最初のタイムスタンプ (N) が前提条件の 1 つ (ディレクトリ、N+x) よりも古いことがわかり、再構築されます。

そして、タイムスタンプがディレクトリより新しくなくなるまで、残りの「古い」前提条件を十分に速く構築できるようになるまで、これは永遠に起こります。

また、一時ファイルやエディターのバックアップ ファイルなどをそのディレクトリにドロップすると、最初からやり直すことになります。

やらないでください。

明示的なシェル コマンドを使用してディレクトリを作成する人もいます。ターゲット作成の副作用としてそれらを作成する人もいます。一部の人々は、注文のみの前提条件を使用して、予定どおりに作成されるようにします。

于 2013-03-01T12:33:52.350 に答える