このようなMakefileルールがある場合:
a b c:
echo "Creating a b c"
touch a b c
output: a b c
cat a b c > output
そして私はmake -j9 outputを実行します
makeは3つの依存関係(a、b、c)を確認し、それらを生成する方法を探します(上記の「a b c」ルール)。しかし、次に何が起こりますか? 「a b c」ルールは、3つのターゲットすべてを作成するために1回実行するだけでよいことを理解していないのですか?
これがmakeが実際に行うことです。
[pavel@orianna 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
[pavel@orianna test]$
同じ出力が3回実行され、依存関係ごとに1回、ルール「出力」が実行されます。
なぜそれがこのように振る舞うのか誰か知っていますか?
君の a b c:
ルールは、これがビルド方法であることをMakeに伝えます どれか 構築方法ではなく、これらのターゲットの すべて そのうちの。 Makeは、コマンドを分析し、一度ルールを実行すると3つすべてがビルドされると推測するほど賢くありません。 output
、a
、およびb
を再構築する必要があることを(c
ルールから)知っておくと、そのようになります。最初のルールは、a
に対して1回、b
に対して1回、c
に対して1回実行されます。
それらを個別に再構築する場合は、次のようにします。
a b c:
echo "Creating $@"
touch $@
それらを一度にすべて再構築したい場合は、次のようにします。
.PHONY: things
things:
echo "Creating a b c"
touch a b c
output: things
cat a b c > output
またはより良い:
THINGS = a b c
.PHONY: things
things:
echo "Creating $(THINGS)"
touch $(THINGS)
output: things
cat $(THINGS) > output
a b cは3つの異なる目標/ターゲットであり、前提条件はありません。つまり、要求されたときにターゲットを構築するということです。
a b c:
echo "Creating a b c"
touch a b c
前提条件としてb cを持つターゲットの名前付き出力をビルドするようにmakeに要求しています。したがって、ターゲットa b cが順次ビルドされ、最終的に出力がビルドされます。
さて、あなたのケースでは、いずれかが呼び出されたときにすべてのターゲットが常にビルドされます。したがって、冗長なビルドを回避するには、ターゲットa、b、cに前提条件を追加する必要があります。 「a」が存在しない場合にのみ、ターゲット「a」をビルドします。同様に「b」と「c」
a b c: $@
echo "Creating a b c"
touch a b c
ただし、これはお勧めできません。理想的には、Makefileターゲットは非常に具体的である必要があります。