2016-11-24 12 views
2

私のmakefileは失敗しました。私の考えは、特定のファイルからファイルを抽出し、それらを一時ディレクトリに置くことでした。これはソースディレクトリにrsyncされます。 rsyncはファイルが変更されたときにのみ更新されるため、ソースディレクトリのmakefileは必要な場合を除いて再作成されません。私は、下の問題を単離した:Makefile複数のターゲット対分離したターゲットは、パターンの結果が異なります。

: 'エキスを作る' '。。PY HHビルド/%ccでビルド/%ビルド/%' を一時に取得させる行う

.PHONY: extract clean 

FILES = filea1.cc filea2.cc filea3.cc      \ 
     filea1.hh filea2.hh filea3.hh      \ 
     filea1.py filea2.py filea3.py      \ 
     dir-cc/filea1.cc dir-cc/filea2.cc dir-cc/filea3.cc \ 
     dir-cc/filea1.hh dir-cc/filea2.hh dir-cc/filea3.hh \ 
     dir-py/filea1.py dir-py/filea2.py dir-py/filea3.py 

PATTERN := $(sort $(addprefix build/%., $(patsubst .%,%,$(suffix $(FILES))))) 

extract: $(addprefix build/, $(FILES)) 

$(PATTERN): 
    mkdir -p $(dir [email protected]); echo "hello!" > [email protected] 

#build/%.cc:;mkdir -p $(dir [email protected]); echo "hello!" > [email protected] 
#build/%.hh:;mkdir -p $(dir [email protected]); echo "hello!" > [email protected] 
#build/%.py:;mkdir -p $(dir [email protected]); echo "hello!" > [email protected] 

temp: 
    echo $(PATTERN) 

clean: 
    rm -rf build 

が、すべてのファイルを作るために失敗しました

build: 
dir-cc dir-py filea1.cc filea2.cc filea3.cc 

build/dir-cc: 
filea1.cc filea2.cc filea3.cc 

build/dir-py: 
filea1.py filea2.py filea3.py 

hhファイルがありません。信じられないことに、実際の作業では、ccファイルがありません。とにかく、$(パターン)をコメントアウトし、上記のコードではターゲットが別々になるように、コメントを削除し、すべてのファイルを取得ん:すべてが実際の作業で自動的に行われる必要があるため

build: 
dir-cc filea1.cc filea1.py filea2.hh filea3.cc filea3.py 
dir-py filea1.hh filea2.cc filea2.py filea3.hh 

build/dir-cc: 
filea1.cc filea1.hh filea2.cc filea2.hh filea3.cc filea3.hh 

build/dir-py: 
filea1.py filea2.py filea3.py 

をし、ルールはすべてのターゲットで同じです(再入力する必要はないはずです)。私は最初のバージョンを大幅に好みます。私はマニュアルを読んでいますが、なぜmakeがこれを行うのか、私は困惑しています。私はGNU Make 4.1を使用しています。

答えて

1

それはPattern Introセクションの最後の段落で説明しています:

パターンルールは複数のターゲットを有することができます。通常のルールとは異なり、これは同じ前提条件とレシピを持つ多くの異なるルールとして機能しません。パターンルールに複数のターゲットがある場合、makeはルールのレシピがすべてのターゲットを作成する責任があることを認識します。レシピはすべてのターゲットを作成するために1回だけ実行されます。

makeが個々のターゲットごとにレシピを1回実行するように、さまざまなパターンターゲットでパターンルールを書き込むことはできません。それはどのように動作するのではありません。あなたがこれを行うことができます

、あなたの非常に単純なケースのために:通常の(非パターン)複数のターゲット ルール$(FILES):;ruleを使用して 調整するパターン固有の変数の値を定義します。

FILETYPES := $(sort $(suffix $(FILES))) 

$(foreach T,$(FILETYPES),$(eval build/%$T: ; mkdir -p $$(@D); echo "hello!" > [email protected])) 
+0

Duh。ありがとう。多くの助けになります。それでも、混乱する。レシピは、make narrates mkdir -p build /以降に複数回実行されたように見えます。エコー "こんにちは!" > build/filea1.cc mkdir -p build /;エコー "こんにちは!" >ビルド/ filea2.cc mkdir -pビルド/;エコー "こんにちは!" > build/filea3.cc mkdir -p build/dir-cc /;エコー "こんにちは!" > build/dir-cc/filea1.cc ... – user2747939

+0

確かに、それは_マッチングパターンごとに1回実行されます。つまり、 'build/filea1.cc'に対して一度実行されますが、makeはこのレシピを一度実行するとターゲットリストに他のパターンも作成されることを期待しています:' build/filea1.hh'と 'build/filea1.pyそれで、それらを別々に構築しようとはしません。しかし、makeは、そのパターンを実行すると、それらのパターンのいずれかと一致する可能性のあるすべてのファイルが作成されるとは考えません。 – MadScientist

+0

これは、このようなことを言うかもしれません。パターンルールには複数のターゲットがある可能性があります。通常のルールとは異なり、これは同じ前提条件とレシピを持つ多くの異なるルールとして機能しません。パターンルールに複数のターゲットがある場合、レシピを実行するたびに、makeはそのレシピの実行時に複数のターゲットリストに一致するすべてのターゲットが作成されたものとみなします。レシピが実際にそのようなすべてのターゲットを構築するように注意する必要があります。これは、ターゲットが一度しか構築しようとしないためです。 – user2747939

0

良好な分解能がありましたルールをファイル拡張子に追加します。

関連する問題