2011-08-16 3 views
24

可能性の重複:
GNU Makefile rule generating a few targets from a single source fileGNUは作る:複数のターゲットを単一のルールに

私はこのようなMakefileのルールがある場合:

a b c: 
    echo "Creating a b c" 
    touch a b c 

output: a b c 
    cat a b c > output 

を、私はを実行しますmake -j9出力

makeは3つの依存関係(a、b、c)を見て、それらの生成方法を探します(上記の "a b c"ルール)。 "a b c"ルールは、3つのターゲットすべてを作成するために一度だけ実行する必要があることに気付かないといけませんか?

これは、実際に作るものではありません:

[[email protected] test]$ make -j9 output -n 
echo "Creating a b c" 
touch a b c 
echo "Creating a b c" 
touch a b c 
echo "Creating a b c" 
touch a b c                                                                  
cat a b c > output                                                                
[[email protected] test]$ 

同じレシピは、かつて「出力」を支配する各依存関係のため、3回を実行しています!

誰でもこのように動作する理由を知っていますか?

+0

関連:http:// stackoverflow。com/questions/3016258/generate-multiple-target-using-single-action-ruleおよびhttp://stackoverflow.com/questions/2973445/gnu-makefile-rule-generating-a-few-targets-from-a-シングルソースファイル – krlmlr

答えて

27

あなたa b c:ルールが、これはそれらのすべてを構築するためにどのようにこれらのターゲットの任意の、ない構築する方法であることを確認してください伝えます。 makeはコマンドを解析するのに十分スマートではなく、一度ルールを実行すると3つすべてを構築すると推論します。 ab、およびcを再構築する必要があることを(outputルールから)知っているので、そのとおりです。それはのために1回、bのためにそしてcのために1回、最初のルールをaのために実行します。

あなたは、それらを個別に再構築し、この実行したい場合は:あなたが一度にすべてを再構築したい場合は

a b c: 
    echo "Creating [email protected]" 
    touch [email protected] 

を、このような何か:

​​

またはより良いまだ:

THINGS = a b c 
.PHONY: things 
things: 
    echo "Creating $(THINGS)" 
    touch $(THINGS) 

output: things 
    cat $(THINGS) > output 
+2

素晴らしい答え!ありがとうございました。偽のターゲットを唯一の方法で作成しているのですか、「a **と** b **と** cはこのルールで構築されています」と表現するためのよりきれいな方法がありますか? – Pavel

+0

@Pavel、私はクリーナーの方法を知らない(と私はおそらく最初のオプションをとるだろう)。しかし、私はまだAUZKamathの答えを理解しようとしています。 – Beta

+12

このシナリオに対処する方法の調査については、http://www.cmcrossroads.com/ask-mr-make/12908-rules-with-multiple-outputs-in-gnu-makeを参照してください。唯一の "正しい" gmakeで複数の出力を持つルールを指定する方法(パターンルール、もちろん!)。 –

6

abcは、前提条件なしの3つの異なる目標/ターゲットです。私は、それが要求されるたびに目標を構築すると言います。

a b c: 
    echo "Creating a b c" 
    touch a b c 

bcを前提条件とするターゲット名付き出力を作成するようにmakeに依頼しています。 ターゲットが順次構築され、最終的に出力が構築されます。

あなたの場合、いずれかのターゲットが呼び出されると、すべてのターゲットが常に構築されます。したがって、冗長ビルドを避けるためには、ターゲットa、b、cに前提条件を追加する必要があります。 'a'が存在しない場合にのみターゲット 'a'をビルドします。 'b'と 'c'についても同様です。

a b c: [email protected] 
    echo "Creating a b c" 
    touch a b c 

ただし、これはお勧めできません。理想的には、Makefileのターゲットは非常に限定的でなければなりません。

+2

これは動作しますが、私はどのように見えません。ジャック・ケリーがあなたを送ったのですか? – Beta

+1

しかし、これを 'make -j3 a b c'で実行すると、3つのジョブが作成されます。 – krlmlr

+2

これはどのように説明できますか?私はそれを説明することはできませんhttps://www.gnu.org/software/make/manual/make.html#index-_0024_0040 – Xiphias

関連する問題