18

次のmakefileは、プリプロセッサが(.dファイルで)依存関係を自動的に生成し、それらをmakefileに含める(私のコースノートにそう書かれているため)ので、自動的に維持する必要がないことを知っています。旗はこれ-MMDに責任があるものです。私が得られないのは:どの時点で.dファイルが生成されますか?使用されるコマンドすらありません${CXXFLAGS}。おそらく、次のようなコマンド${CXX} ${CXXFLAGS} -c x.C -o x.o各オブジェクトファイルのmakeによって自動的に推定されますが、これらが.dファイルを生成するコマンドである場合、xo、yo、およびzoの依存関係を知ることが関連している可能性があるポイントをすでに通過していません。 、これらの.oファイルを生成するコマンドを実行することによってのみそれらを知っている場合はどうなりますか?(それ自体または何かでルールを推測するために残された場合、makefileが無視する.hファイルがあるとしましょう。)

CXX = g++                     # compiler
CXXFLAGS = -g -Wall -MMD      # compiler flags
OBJECTS = x.o y.o z.o         # object files forming executable
DEPENDS = ${OBJECTS:.o=.d}    # substitutes ".o" with ".d"
EXEC = a.out                  # executable name

${EXEC} : ${OBJECTS}          # link step
    ${CXX} ${OBJECTS} -o ${EXEC}

-include ${DEPENDS}           # copies files x.d, y.d, z.d (if they exist)
4

3 に答える 3

15

おそらく、のようなコマンド${CXX} ${CXXFLAGS} -c x.C -o x.oは、オブジェクトファイルごとにmakeによって自動的に推測されますが、これらが.dファイルを生成するコマンドである場合、xo、yo、およびzoの依存関係を知ることができるポイントをすでに通過しているのではないでしょうか。これらの.oファイルを生成するコマンドを実行することによってのみそれらを知っている場合、関連性がありますか?

あなたはここで正しいです。Makefileを初めて実行するとき、依存関係は存在しません。

ただし、これは重要ではありません。依存関係情報が必要になるのは、.oファイルがすでに存在し、.hファイルを変更した場合のみです。初めてMakeを実行するときは、とにかくすべての.oファイルをビルドする必要があり、.dファイルは同時に生成されます。

その後、.dファイルは依存関係情報を提供します。ヘッダーが変更された場合、依存関係情報は、どの.oファイルを再構築する必要があるかをMakeに通知します。ソースファイルが変更された場合、.oは常に再構築する必要があり、同時に更新された依存関係情報が生成されます。

于 2012-08-08T05:27:05.757 に答える
2

背後にあるmakefileによって何が行われているのか疑問に思った場合は、-pフラグを使用して、出力をファイルにリダイレクトしてください。

make -p foo > barのすべての変数値とルールをダンプしmake foo、次に調べるとbar、暗黙のルールに対して実行されているコマンドが表示されます。あなたの場合、.cpp.oor %.o: %.cpp(奇妙なことに両方がそこにある)ルールがどちら$(COMPILE.cpp)を解決するかを呼び出すことを示しているでしょ$(COMPILE.cc)$(CXX) $(CXXFLAGS) $(CPPFLAGS) $(TARGET_ARCH) -c。これには、CXXFLAGSまたはCPPFLAGSのいずれかに追加して.cpp.oコンパイルに組み込むことができるという興味深いプロパティがありますが、.c.oルールでのみ使用されるCFLAGSはありません。これは、おそらくCファイルが必要なため少し意味があります。およびC++ファイルの処理方法は異なります(通常、CCとCXXも異なるコンパイラーに設定されます)。

于 2015-10-05T01:16:39.243 に答える
0

はい、その通りです。依存関係ファイルを削除してもオブジェクトファイルをそのままにしておくと、makeは不完全な依存関係情報で実行され、ヘッダーが変更されたオブジェクトファイルの再構築に失敗する可能性があります。

Makeはビルドを拒否する場合もあります。これは、依存関係ファイルが削除したヘッダーを参照している場合に発生します(明らかに、他のソースからの参照はなくなります)。Makeはコンパイル前に依存関係ファイルを再構築する方法を知らないため、依存関係の欠落を報告するだけです(そして、明らかなアクションは依存関係ファイルを削除することであり、上記の最初の条件につながります)。

これに対する唯一の答えは規律です。依存関係ファイルを削除するときは、常にオブジェクトファイルを削除してください。cleanターゲットを使用してこれを支援できます。

clean::
        $(RM) *.o *.d

または、さらに、依存関係ファイルの作成方法をMakeに指示します。

%.dep: %.cc
        $(CXX) -MM $(CPPFLAGS) $< | sed -e 's,\($*\)\.o[ :]*,\1.o $@: ,g' > $@

(このsedコマンドは、依存関係自体がオブジェクトファイルと同じソースに依存していることを確認します)。

于 2016-10-25T08:17:10.170 に答える