1

g++ -MMこの機能を使用して、依存関係を自動構築するのが好きです。私がこれを行う方法は次のとおりです。

include $(ALLOBJ:%.o=%.d)

%.d: %.cxx
    @echo making dependencies for $<
    @g++ -MM $(CXXFLAGS) $< -o $@
    @sed -i 's,$*\.o,& $@ ,g' $@

基本的に、私はこのルールを与えることができALLOBJ、それは次のようになります:

  1. .oすべての名前を名前に.d変換するincludeと、
  2. が見つからない場合は、ファイル .dから作成します.cxx
    • %.d: %.cxxルールの最後の行は.d、依存関係が自動的に更新されるように、ファイルの名前をファイル自体に追加します。

この問題は、ヘッダーを削除したときに発生します。.dファイルはまだそれを見つけることを期待しており、そこにない場合、make は動揺します。1 つの解決策は、 に置き換えinclude-include、コンパイル ルール内で依存関係を構築することです。残念ながら、これにはコンパイル ルールごとに依存関係を生成する行が必要であり、他のすべてのincludeエラーも無視されます (これはリスクが高いと思われます)。この問題を回避する依存関係を自動構築する他の簡単な方法はありますか?

4

2 に答える 2

2

のマニュアルをもう少し読んで、上記の@jackKellyと@Betaの応答のおかげで、次の解決策を見つけました。

include $(ALLOBJ:%.o=%.d)

%.d: %.cxx
    @echo making dependencies for $<
    @g++ -MM -MP -MT $*.d -MT $*.o $(CXXFLAGS) $< -o $@

フラグを要約するには:

  • -MM:依存関係を構築する(コンパイルするのではなく)
  • -MP:すべてのヘッダーの「ダミー」ターゲットを作成します。これにより、ヘッダーが削除されて見つからない場合にmakeが文句を言うのを防ぎます。
  • -MT:ルールのターゲットを指定します。これにより.d、醜いsedルールに頼ることなく、ファイルがヘッダーに依存するようにすることができます。

私の解決策が@Betaの解決策よりも正しいとは思わない。私は同じmakefile内のC++ファイルに対して複数のコンパイルルールを使用する傾向があるため、すべてのファイルに単一の依存関係ルールを設定する方が、各コンパイルルールで依存関係を生成するよりも少しクリーンです(私の場合)。

于 2012-10-13T19:43:18.077 に答える
2

他の質問に対する私の答えを言い換えるには、次のようにします。

%.o: %.cpp
    @echo making $@ and dependencies for $< at the same time
    @$(CC) -MD -c $(CXXFLAGS) -o $@ $<
    @cp $*.d $*.P
    @sed -e 's/#.*//' -e 's/^[^:]*: *//' -e 's/ *\\$$//' \
         -e '/^$$/ d' -e 's/$$/ :/' < $*.P >> $*.d
    @rm $*.P

-include $(ALLOBJ:%.o=%.d)

編集:

それは...依存ファイルを生成しますが、よりクリーンでsedコマンドなしで:

%.o: %.cpp
    @echo making $@ and dependencies for $< at the same time
    @$(CC) -c $(CXXFLAGS) -o $@ $<
    @$(CC) -MM -MP $(CXXFLAGS) $< -o $*.d

-include *.d

%.oそのため、独自のメイクファイルでルールを変更する必要があります。これからは、私がコンパイルするすべてのものに@JackKelly が少しあり、私を嘲笑します。ああ、これは黒い日です。

于 2012-10-12T23:02:08.913 に答える