2016-12-08 8 views
0

私は中間ステップとして.ecファイルから.cファイルを生成するコンパイラを持っています。コンパイラは.cファイルを削除しません。 .oファイルを生成するために、$ CCの呼び出しをスキップするようコンパイラーに要求することはできません。 GNU make(3.81)に中間ファイルとして生成された.cファイルを扱い、それらをクリーンアップさせようとしています。以下は、暗黙の規則を持たないファイル拡張子で悪い動作を再現する独立した例です。 GNU中間ファイルを強制的に削除する

.INTERMEDIATE: %.delme 

%.o: %.ec 
     cp $< $(<:.ec=.delme) 
     cp $(<:.ec=.delme) [email protected] 

all: test.o 

は、テストケースを実行するには、次の

rm -f test.* 
touch test.ec 
make 
if [[ -e test.delme ]]; then echo "Failure"; else echo "Success"; fi 

答えて

1

はそのコンパイラが.ECソースからの.oと.cファイルの両方を生成作る伝えるためにパターンルールを使用してみてください。そして、すべてのcファイルをINTERMEDIATEとして宣言します。複数の出力を持つパターンルールは、非パターンルールとは異なる働きをします。 makeはルールからすべての出力ファイルを生成するためにパターンルールを1回だけ実行し、出力ファイルごとに静的ルールが実行されます。パターンルールは、それらのうちの1つだけをターゲットとして望む場合でも、すべての出力ファイルを生成することを理解してください。

SRC := foo.ec bar.ec 
OBJS := $(SRC:.ec=.o) 

all: program 

program: $(OBJS) 
     cat $^ > [email protected] 

%.o %.c: %.ec 
     cp $< $(<:.ec=.c) ; cp $< $(<:.ec=.o) 

.INTERMEDIATE: $(SRC:.ec=.c) 

コマンド.ECから.Cとの.oは、それらのファイルの両方を生成するために、一度に実行されるようにする:

結果はこのようなものです。 makeはそれが.cを作ったことを知っているので(.oだけが欲しかったとしても)、それを削除するのに十分な知識があります。 .INTERMEDIATEターゲットは、パターンを使用せず明示的にファイルがリストされている場合にのみ機能するため、%.cは使用していません。とにかく、悪い考えのように思えますが、.ecファイルから生成されていないCソースがあり、それをあなたのために削除したらどうでしょうか?出力例:

bar.o/cが再構築されていないので、2回目の呼び出しでfoo.cが削除されたことに注意してください。

+0

これは私の簡単なcpの例では動作しますが、クロスコンパイラでは動作しません。なぜ私は正確にはわからない。私は特定の状況のた​​めにrmソリューションに落ちましたが、これはより慣用的なソリューションだと思います。だから私はこれを受け入れられた答えにしているのです。 –

1

メイクは唯一の中間であることを目標に行うことを検討することができます。ファイルシステム上にランダムなファイルを中間ファイルとして宣言するだけで、それを削除することはできません。

ここで.delmeファイルは、.oファイルを作成するレシピのの副作用として作成されます。 makeはそれについて何も知らないのでmakeは中間ファイルであるmakefileにターゲットがないので、makeはそれを削除しません。あなたの例では

あなたは別のルールに2つのcpコマンドを分割可能性があり、それは中間の設定が機能するようになります。

%.delme : %.ec 
     cp $< [email protected] 
%.o : %.delme 
     cp $< [email protected] 

私はあなたの本当の環境であなたが原因ということはできないと仮定しています中間ファイルと実際のファイルを生成するコマンドはすべて1つです。その場合、あなたはレシピの内側に自分自身を削除するに対処する必要があります:これはcpコマンドが失敗した場合、既存の.delmeファイルを残し

%.o : %.ec 
     cp $< $(<:.ec=.delme) 
     cp $(<:.ec=.delme) [email protected] && rm -f $(<:.ec=.delme) 

注意。あなたがそれを何でもすることができてもそれを削除したい場合。コマンドは、あなたはそれが何であったかmakeを伝えることができるように、終了コードを維持する必要が失敗した場合でも、中間ファイルを削除するには

EDIT

。ような何か:

%.o : %.ec 
     cp $< $(<:.ec=.delme) 
     cp $(<:.ec=.delme) [email protected]; e=$$?; rm -f $(<:.ec=.delme); exit $$e 
+0

ありがとうございました!私のnieveアプローチは、副作用ファイルでrm -fを実行することでした。コマンドが失敗しても削除する方法を示すために例を更新できますか?私はそれを理解することができませんでした。 –

+0

更新された回答。 – MadScientist

+0

ありがとう!私はまだシェルコマンドを呼び出す方法を把握しているので、これは明らかではありません。私は本当にあなたが答えを拡大する時間を割いてくれてありがとう。 –

関連する問題