0

プロジェクトのバイナリといくつかの単体テストのバイナリのビルドをサポートするために Makefile を更新しようとしています。

私のディレクトリ構造は次のとおりです

|-code/
|--|--src/
|--|--inc/
|
|-tests/
|--|--src/
|--|--inc/

私のメイクファイルはコードからバイナリをうまくコンパイルしますが、テストでいくつかの問題があります。test フォルダーには、code/src/ のいくつかのクラスをテストする単体テストが含まれています。main() 関数を含む code/src/ にファイル main.cpp と、独自の main() 関数を含む tests/src に test.cpp という別のファイルがあります。

これにより、次の複雑な Makefile にたどり着きました。

CC = g++
FLAGS = -g -c -Wall

INCLUDEDIR = -Icode/inc -Itests/inc
BUILDDIR = build

SOURCEDIR = code/src
SOURCES = $(wildcard $(addsuffix /*.cpp,$(SOURCEDIR)))
TEMP_OBJ = $(SOURCES:%.cpp=%.o)
NOT_DIR = $(notdir $(TEMP_OBJ))
OBJECTS = $(addprefix $(BUILDDIR)/, $(NOT_DIR))

TEST_DIR = tests/src
TEST_SOURCES = $(wildcard $(addsuffix /*.cpp,$(TEST_DIR)))
TEST_TEMP_OBJ = $(TEST_SOURCES:%.cpp=%.o)
TEST_NOT_DIR = $(notdir $(TEST_TEMP_OBJ))
TEST_OBJECTS = $(addprefix $(BUILDDIR)/, $(TEST_NOT_DIR))

EXECUTABLE = Client
TEST_EXECUTABLE = TestUnit

all: $(BUILDDIR) $(BUILDDIR)/$(EXECUTABLE) $(BUILDDIR)/$(TEST_EXECUTABLE)

$(BUILDDIR):
    mkdir -p $@

$(BUILDDIR)/$(EXECUTABLE): $(OBJECTS)
    $(CC) $^ -o $@

$(BUILDDIR)/%.o : code/src/%.cpp
    $(CC) $(FLAGS) $< $(INCLUDEDIR) -o $@

$(BUILDDIR)/$(TEST_EXECUTABLE): $(OBJECTS) $(TEST_OBJECTS)
    @rm -f $(BUILDDIR)/main.o
    $(CC) $^ -o $@

$(BUILDDIR)/%.o : tests/src/%.cpp
    $(CC) $(FLAGS) $< $(INCLUDEDIR) -o $@

clean:
    rm -rf $(BUILDDIR)

次のエラーで失敗します。

g++: error: build/main.o: No such file or directory
make: *** [build/TestUnit] Error 1

これは、次の行があるためです。

@rm -f $(BUILDDIR)/main.o

しかし、それ以外の場合はエラーが発生します (それぞれ main.cpp に main があり、code/src/ と tests/code/ に test.cpp があります):

/tests/src/test.cpp:7: multiple definition of `main'
code/src/main.cpp:6: first defined here
collect2: error: ld returned 1 exit status

私の Makefile には多くの重複があります。コードは共有されていますが、これら 2 つのフォルダーから 2 つのバイナリを構築するという目的を達成する、より簡潔なものを入手したいと考えています。

任意の助けをいただければ幸いです。どうもありがとうございました!

4

1 に答える 1

1

このメイクファイルには多くの問題があります。

まず、 などのテスト オブジェクト ファイルを作成するルールはありませんtest.o。オブジェクトを構築するための唯一の規則は、ソースが にあることを必要としcode/src/ます。リンカのエラーが表示されるまで、どのようにすればよいのかわかりません。

オブジェクト ルールを静的パターン ルールに変更しましょう。

$(OBJECTS) : $(BUILDDIR)/%.o : code/src/%.cpp
    $(CC) $(FLAGS) $< $(INCLUDEDIR) -o $@

次に、テスト オブジェクトに追加のルールを追加できます。

$(TEST_OBJECTS) : $(BUILDDIR)/%.o : tests/src/%.cpp
    $(CC) $(FLAGS) $< $(INCLUDEDIR) -o $@

(今のところ、冗長性は気にしないでください。最初に機能させる必要があります。)

これで、このルールでリンカー エラーが表示されるはずです。

$(BUILDDIR)/$(TEST_EXECUTABLE): $(OBJECTS) $(TEST_OBJECTS)
    ...

その前提条件のリストには 2 つのファイルがmain.oあり、test.o誰が定義するかをめぐって争っていますmain()。が必要test.oなので、main.o行かなければなりません:

$(BUILDDIR)/$(TEST_EXECUTABLE): $(filter-out build/main.o,$(OBJECTS)) $(TEST_OBJECTS)
    ...

これだけ試して、結果を教えてください。機能したら、スリム化できます。

于 2013-07-31T20:31:01.260 に答える