2013-07-31 100 views
0

我試圖更新我的Makefile以支持構建我的項目的二進制文件,以及一些單元測試的二進制文件。Makefile支持2個可執行文件

我的目錄結構如下

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

我的makefile文件彙集了來自碼二進制很好,但有與測試的一些問題。測試文件夾包含一些單元測試,用於測試code/src /中的某些類。我在代碼/ src /中包含main()函數的main.cpp文件,以及另一個名爲test.cpp的文件,該文件在tests/src中包含自己的main()函數。

這使我這個複雜的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 [email protected] 

$(BUILDDIR)/$(EXECUTABLE): $(OBJECTS) 
    $(CC) $^ -o [email protected] 

$(BUILDDIR)/%.o : code/src/%.cpp 
    $(CC) $(FLAGS) $< $(INCLUDEDIR) -o [email protected] 

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

$(BUILDDIR)/%.o : tests/src/%.cpp 
    $(CC) $(FLAGS) $< $(INCLUDEDIR) -o [email protected] 

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和test.cpp分別在code/src /和tests/code /中有main):

/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個二進制文件的目的,雖然代碼是共享的。

任何幫助,將不勝感激。非常感謝你!

+0

我認爲'code/src/main.cpp'有'main()'。 'tests/src /'中源文件的名稱也是'main()'? – Beta

+0

你說得對,main.cpp有一個main()。它在test/src /中包含另一個main()。謝謝! – Jary

回答

1

這個makefile有很多問題。

首先,沒有建立測試對象文件的規則,比如test.o。構建對象的唯一規則要求源代碼位於​​;我不知道你甚至能夠看到鏈接器錯誤。

讓我們改變物體規則靜態模式規則:

$(OBJECTS) : $(BUILDDIR)/%.o : code/src/%.cpp 
    $(CC) $(FLAGS) $< $(INCLUDEDIR) -o [email protected] 

然後,我們可以添加額外的規則來進行測試對象:

$(TEST_OBJECTS) : $(BUILDDIR)/%.o : tests/src/%.cpp 
    $(CC) $(FLAGS) $< $(INCLUDEDIR) -o [email protected] 

(不要介意爲now--冗餘我們已經得到它的第一個工作日)

現在我們應該看到一個鏈接錯誤在這條規則:

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

的先決條件中的該名單有兩個文件,main.otest.o爭食誰可以定義main()。我們希望test.o,所以main.o一定要去:

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

嘗試這麼多,告訴我們結果。一旦工作,我們可以減少它。

+0

回答你的第一條評論:TEST_DIR = tests/src有一條規則,它被設置爲TEST_OBJECTS(對於類似test.o)。規則:$(BUILDDIR)/ $(TEST_EXECUTABLE):$(OBJECTS)$(TEST_OBJECTS)創建TEST_OBJECTS,它使用$(BUILDDIR)/%。o:tests/src /%。cpp。我會盡力解決您的問題,並會盡快報告。謝謝! – Jary

+0

@Jary:對不起,我錯過了。一旦我們解決衝突,我會糾正我的答案。 – Beta

+0

沒問題!這是一個很大的Makefile,裏面充滿了重複的條目,這是我的錯誤:) – Jary

相關問題