2012-12-27 6 views
6

Makefileに再利用可能コードを書き込むベストプラクティスは何ですか?再利用可能なコードを書き込むためのベストプラクティス

私はMakefileを持っていると仮定します。

.PHONY: all task01-all task01-clean task01-run task02-all task02-clean task02-run 

all: task01-all task02-all 

############################################################################### 
task01-all: task01-clean task01 task01-run 

task01-clean: 
    rm task01 task01.{exi,o} -f 

task01: 
    compiler task01.ext -O2 --make 

task01-run: 
    ./task01 

############################################################################### 
task02-all: task02-clean task02 task02-run 

task02-clean: 
    rm task02 task02.{exi,o} -f 

task02: 
    compiler task02.ext -O2 --make 

task02-run: 
    ./task02 

今、私はタスク(task03)の新ファミリを追加したい、と私は、全体のセクションをコピー - ペーストそれのためs/02/03/を作り、.PHONYセクションに追加する必要があります - それはです騒々しい、嫌な、ちょうど正しくない。

どうすれば避けることができますか?テンプレートを使ってすべてのタスクを何とか再定義して、新しいタスクグループを1行に追加するための素敵な仕組みを作ることができますか?

答えて

9

それはあなたが.PHONYターゲットを言及して以来使用しているものです)。あなたが作るの依存性チェックのいずれかを使用していない場合は、それはシェルスクリプトでこれを行うには簡単かもしれ - のようなもの:

#!/bin/sh 
TASKS="task01 task02 task03" 

for i in $TASKS; do 
    rm $i $i.ext $i.o -f; 
    compiler $i.ext -O2 --make; 
    ./$i; 
done 

をしかし、作るために原則を拡張するために、我々は別の問題を持っていますタックルする。フォームの行:

task01-all: task01-clean task01 task01-run 

前提条件を構築するどのような順序にしてください教えていない - 彼らはすべてのtask01-allが構築される前に行われる必要があるだけのこと。代わりに、実行する各ステップは、その前のステップに依存する必要があります。このような何か:%

TASKS=task01-run task02-run task03-run 

.PHONY: all $(TASKS) $(TASKS:run=clean) 

all: $(TASKS) 

$(TASKS:run=clean): %-clean: 
    rm $* $*.ext $*.o -f 

%: %.ext | %-clean 
    compiler $< -O2 --make 

$(TASKS): %-run: % 
    ./$< 

ルールは、「パターンルール」と呼ばれる、と彼らは異なるターゲットのための再書き込みと同じルールを複数回を回避するための素晴らしいツールですされています。 1つの注意点は、Makeが通常.PHONYターゲットのパターンルールをチェックしていないことです。これらのルールにターゲットのリストと第2のコロン(例えば、$(TASKS):)を接頭辞として付けることによって、明示的にこれを行うようにします。

task01-runは作業するためにtask01が必要なので、%-runのターゲットは%に依存しています。また、メイクファイルには毎回きれいに実行したいので、%%-cleanに依存しています。 %-cleanは実際には出力を生成しませんので、これを「注文のみ」の依存関係にします.Makeはタイムスタンプなどを探すことはありません。%を実行する必要があるときは常に%-cleanルールを実行しますルール。 「注文のみ」の依存関係が|後に置かれています。

%: %.ext | %-clean 

それはメイクの最大の強みの一つは、それが繰り返されることを必要としない作業を繰り返していないことで時間を節約することができるということであることを言及する価値がある - すなわち、それは依存関係がターゲットよりも新しい場合にのみルールを実行します。

%: %.ext 
    compiler $< -O2 --make 

をあなたはその後、ちょうど%-clean目標のすべてを実行するためにルールを追加することができます::

だから、あなたは %.ext%より新しい場合のみ compiler $< -O2 --makeを実行するために作る原因と思われる、 %-cleanの依存をオフに残すことができます
.PHONY: all $(TASKS) $(TASKS:run=clean) clean 

clean: $(TASKS:run=clean) 

最後のもの:私はレシピでいくつかの特殊変数を使用します。 [email protected]は、ビルド対象の略です。 $<は最初の依存関係を表します。 $*は、パターンルールの「ステム」(つまり、%と一致する部分)を表します。

+0

良い説明。ありがとう! –

+0

"|"の例を指定すると、ありがとう、ありがとう。 –

2

私が探しています何のように見える:質問はMakefileの中で再利用可能なコードを書くことについてですので、私は(それが見えるようにGNUにパターンルールを使用する方法の例をあげる

ALLS=task01-all task02-all 
BUILDS=${ALLS:-all=-build} 
CLEANS=${ALLS:-all=-clean} 
RUNS=${ALLS:-all=-run} 

.PHONY: all $(ALLS) $(CLEANS) $(BUILDS) $(RUNS) 

all: $(ALLS) 

############################################################################### 
$(ALLS): $(CLEANS) $(BUILDS) $(RUNS) 

$(CLEANS): 
     rm ${@:-clean=} ${@:-clean=}.{ext,o} -f 

$(BUILDS): 
     compiler ${@:-build=}.ext -O2 --make 

$(RUNS): 
     ./${@:-run=} 
関連する問題