5

いくつかの依存関係の生成を実行する Makefile を作成してきましたが、(レガシー) コードベースには.cpp.ccファイルが混在しているため、ルールを複製する必要があることに気付きました。少し見栄えが悪いようです。.cppターゲットの前提条件がファイルまたはファイルのいずれかになるように指定する方法はあり.ccますか?

したがって、次のようにするのではなく:

%.d : %.cpp
    $(CPP) -MM $(CPPFLAGS) $<

%.d : %.cc
    $(CPP) -MM $(CPPFLAGS) $<

次のような重複のないものを作成します。

%.d : %.(cpp | cc)
    $(CPP) -MM $(CPPFLAGS) $<

それとも、この強制された冗長性は、GNU Make の設計の不幸な要素にすぎないのでしょうか?

4

2 に答える 2

3

最初のオプションでは、変数を使用してルール本体を一度定義し、必要に応じて再利用します。

DEPGEN=$(CPP) -MM $(CPPFLAGS) $<
%.d: %.cpp ; $(DEPGEN)
%.d: %.cc  ; $(DEPGEN)

2 番目のオプションは$(eval)、ルールを動的に生成するために使用します。

$(foreach src,cpp cc,$(eval %.d: %.$(src) ; $$(CPP) -MM $$(CPPFLAGS) $$<))
于 2011-08-24T00:52:35.480 に答える
1

これはうまくいくはずです:

%.d :: %.cpp
    $(CPP) -MM $(CPPFLAGS) $<

%.d :: %.cc
    $(CPP) -MM $(CPPFLAGS) $<

別のアイデア:

%.d : %.c
    $(CPP) -MM $(CPPFLAGS) $<

%.c : %.cpp
    ln $< $@  # or cp -p

もう 1 つのアイデアは、GNU make に 2 つのパターン ルールを生成させることです。これには、基本的に次の 2 つの方法があります。

  • %-cc.mkGNU makeの includeステートメントを使用して実際のmakefileに含めるmakefile(または同様のもの)にそれらを書き込みます
  • $(eval)GNU makeおよび$(call)関数を使用してインラインで生成および評価する

C/Unix 開発ツールチェーンの他のほとんどすべてと同様に、これらの手法は本質的に前処理の形式であり、使いにくいという代償を払って理解しやすくしています (二重または三重のエスケープが多く、何を追跡するのが非常に難しい)。少なくとも私の経験では、デバッグは王室の苦痛になる可能性があります)。

そのため、より複雑なユースケースのためにそれらを予約してください (そのうちのいくつかは Stack Overflow にリストされています)。

于 2011-08-22T18:15:29.117 に答える