0

私はGNUmakefileについての知識が限られていますが、現時点では失敗しています。

クラス宣言ファイルmdfTree.h、クラスmdfTree.cppの実装、およびクラスmdfTreeのオブジェクトを作成し、そのパブリック関数を呼び出してプライベートメンバーを呼び出すメインのmdfTree_x.cppファイルがあります。 mdfTreeの変数。

私はそれをMakefileでコンパイルしています:

CXX=g++
CXXFLAGS=-g -Wall -W -Wconversion -Wshadow -Wcast-qual -Wwrite-strings $(shell root-config --cflags --gl\
ibs)
LDFLAGS=-g $(shell root-config --ldflags)
LDLIBS=$(shell root-config --libs)

mdfTree_x: mdfTree_x.o
        g++ $(LDFLAGS) -o mdfTree_x mdfTree_x.o $(LDLIBS)

mdfTree_x.o: mdfTree_x.cpp
        g++ $(LDFLAGS) $(CXXFLAGS) -c mdfTree_x.cpp

mdfTree.cppとmdfTree_x.cppにはが含ま#include mdfTree.hれています。mdfTree_x.cppも必要#include mdfTree.cppですか?

コンパイルしようとすると、クラスmdfTreeのパブリック関数が同じクラスのプライベート変数を認識できないため、Makefileが間違っていると思います。また、構文エラーをmdfTree.hに挿入すると、コンパイラはそれを取得しません。mdfTree_xがmdfTree.h/.cppを使用/コンパイルする必要があることをMakefileに伝えるにはどうすればよいですか?

4

3 に答える 3

2

mdfTree.cppもコンパイルおよびリンクするために、makeファイルを調整する必要はありません。

このようなもの

mdfTree.o: mdfTree.cpp
        g++ $(LDFLAGS) $(CXXFLAGS) -c mdfTree.cpp

リンクステップをに変更します

mdfTree_x: mdfTree_x.o mdfTree.o
        g++ $(LDFLAGS) -o mdfTree_x mdfTree_x.o mdfTree.o $(LDLIBS)
于 2012-10-23T12:15:36.213 に答える
1

すべての依存関係を明示的に追加する必要があります。この場合、実行可能ファイルはビルドされたmdfTree.oに依存し、mdfTree.oとmdfTree_x.oはmdfTree.hに依存します。あなたの依存関係は次のようになります

mdfTree_x:mdfTree_x.o mdfTree.o
mdfTree.o:mdfTree.cpp mdfTree.h
mdfTree_x.o:mdfTree_x.cpp mdfTree.h

一部のコンパイラ(gnuやi​​ntelなど)は、ヘッダーの依存関係をmake形式で自動的に一覧表示できます。たとえば、このmakefileはmdfTree_x.cppmdfTree.cppまたはmdfTree.hが変更されたときに実行可能ファイルを再生成します。

# Compiler flags...
CPPFLAGS+=-MMD -MP
mdfTree_x:mdfTree_x.o mdfTree.o
-include mdfTree_x.d mdfTree.d

CPPFLAGSは、コンパイル時にヘッダー依存関係を持つ.dファイルを作成します。-include行は、存在する場合はこれらをmakefileに含めようとします(存在しない場合は、ソースファイルが再コンパイルされるため、追加の依存関係はありません。重要)。.dファイルの内容は次のようになります

mdfTree.o:mdfTree.h

また、ほとんどの場合、makeルールを明示的に記述する必要はありません。たとえばfoo.o、依存関係としてリストされているファイルがある場合、gnumakeのデフォルトルールが実行されます。

$(CXX) $(CPPFLAGS) $(CXXFLAGS) -c -o foo.o foo.cpp

(他の言語でも同様です)。同様に、実行可能ファイル名がオブジェクトファイルの1つと一致する場合、リンクは自動的に行われます。

foo:foo.o

実行されます(CXXではなくCCに注意してください)

$(CC) $(LDFLAGS) -o foo foo.o $(LDLIBS)

デフォルトのルールを使用すると、makefileが単純になり、環境変数を使用してデフォルトのコンパイラを設定することもできます。

于 2012-10-23T12:34:04.600 に答える
1

クラス宣言ファイルmdfTree.h、クラスmdfTree.cppの実装、およびクラスmdfTreeのオブジェクトを作成し、そのパブリック関数を呼び出してプライベートメンバーを呼び出すメインのmdfTree_x.cppファイルがあります。 mdfTreeの変数。

プログラムには、mdfTree.cppとmdfTree_x.cppの両方で定義された機能が必要です。したがって、これらのファイルの両方をコンパイルする必要があり、リンクにはmdfTree.oとmdfTree_x.oの両方を組み込む必要があります。

2つのルールを記述できます。1つはmdfTree.cppをコンパイルするためのもので、もう1つはmdfTree_x.cppをコンパイルするためのものです。これはすぐに手に負えなくなります。悪になりなさい。それらすべてを構築するための1つのルール、それらを見つけるための1つのルール、それらすべてをもたらし、暗闇の中でそれらをバインドするための1つのルール。

objects = mdfTree_x.o mdfTree.o
$(objects): %.o: %.cpp
   g++ $(CXXFLAGS) -c $<

$(LDFLAGS)上記のコンパイルルールにはないことに注意してください。コンパイル時にリンクオプションを指定しないでください。

オブジェクトをリンクして実行可能ファイルを形成する必要があります。

mdfTree_x: $(objects)
   g++ $(LDFLAGS) -o $@ $^ $(LDLIBS)

ここで、リンカーオプションを指定する必要があることに注意してください。あなたはリンクしています。

次のステップの前の最後のポイント:一般に、makefileでルールを指定する順序は重要ではありません。ただし、例外が1つあります。make最初のルールはデフォルトのルールであり、コマンドでターゲットをまったく指定しない場合に使用されるルールです。デフォルトのルールをmakefileの最上部近くに明示的に配置することをお勧めします。たとえば、makefileの先頭近くに、他のルールの前に次のように配置します。

default: mdfTree_x

mdfTree.cppおよびmdfTree_x.cppには、#includemdfTree.hが含まれています。mdfTree_x.cppには#includemdfTree.cppも必要ですか?

#includeソースファイルは絶対に使用しないでください。一度もない。リンカにそれをさせてください。

ただし、ここには何か足りないものがあります。mdfTree.hを変更するとします。再構築する必要があります。これまでのmakefileはそれを行いません。欠落しているのは、mdfTree.hへの依存関係です。この場合、この依存関係の問題に対する簡単な解決策があります。依存関係を指定するだけです。

$(objects): mdfTree.h

一般に、このヘッダー依存関係の問題は非常に難しい問題です。これらのヘッダーファイルの依存関係をmakefileに入れないのが最善です。makedependそれらの依存関係を把握するなどの自動化ツールを使用してください。

于 2012-10-23T12:55:37.613 に答える