14

マニュアルに従って、 gmakeとgcc -MMヘッダーの依存関係を追跡しています。このメカニズムは、計算された依存関係をインポートするためにmakefileディレクティブに依存しています。include

ファイルはmakefileに含まれているため.d、を含むすべてのターゲットを作成するには、ファイルが存在している必要がありますclean。したがってclean、正しいことを行う前に、依存関係を生成する必要があります。ビルドに失敗した場合は、cleanさらに混乱を招きます。

さらにclean、ターゲットを構築する前にすべての依存関係を作成する必要があります。

さらに、存在しないファイルを含むようにファイルが変更された場合、依存関係の解決が失敗し、何も構築されません。

ヘッダーが削除された場合でも、既存の依存関係ファイルにはターゲットとして名前が付けられたままであり、問​​題のある依存関係ファイルが削除されるまで何もビルドされません…これは。では実行できませんclean

の置換パターンをincludeワイルドカードに置き換えて既存の依存関係ファイルをすべて含めると、いくつかの問題は解決しますが、壊れた依存関係をクリーンアップすることはできず、古い依存関係ファイルが削除されることはありません。より良い解決策はありますか?マニュアルの例は本当に実際の使用を目的としていますか?

4

3 に答える 3

19

ファイルを生成するためのルールを提供しないでください.d。GNU MakeのメンテナーであるPaul Smithの「Advanced Auto-Dependency Generation」で、なぜそれがあまり良くないのか(あなたのケースも含めて)の良い説明が得られます。

一言で言えば、次のパターンはすべてのケースでうまく機能します。

CPPFLAGS += -MMD -MP

%.o: %.c
    $(CC) $(CPPFLAGS) $(CFLAGS) -o $@ -c $<

-include $(OBJS:.o=.d)

私の以前の関連する回答も参照してください。

于 2012-10-12T10:56:25.660 に答える
9

解決策は、条件付き構文を使用することです:

ifneq ($(MAKECMDGOALS), clean)
-include $(notdir $(SOURCES:.cpp=.d))
endif

これにより、クリーン ターゲットは*.dターゲットを呼び出さなくなります。これは、実行時make clean*.dファイルが Makefile に含まれないためです。

参考:https ://www.gnu.org/software/make/manual/html_node/Goals.html

于 2015-11-03T03:43:38.987 に答える
2

私の通常のパターンは次のようになります

all: target
target: .depends

## [snip build rules]

.depends:
     gcc -MM $(CPPFLAGS) .... > $@

-include .depends

-includeの代わりに注意してくださいinclude。基本的に、条件付きで含まれます:つまり、iffファイルが存在します

ドキュメントを参照してください: http://www.gnu.org/software/make/manual/make.html#Include

于 2012-10-12T10:52:35.687 に答える