2017-02-13 73 views
0
重複的規則數量

的目標是指定一個構建目錄中的.o和可執行將駐留建設項目減少makefile文件

目前我寫這個Makefile執行此之後,但我必須指定手動爲每個目標文件的目錄。

PROGNAME = parkingLotApp 

CXX   = g++ 

SRC   = main.cpp \ 
     parking_car.cpp \ 
     parking_lot.cpp \ 
     shader.cpp \ 
     shader_manager.cpp 


OBJS  = main.o \ 
     parking_car.o \ 
     parking_lot.o \ 
     shader.o \ 
     shader_manager.o \ 


BUILDIR  = build 

CXXFLAGS = -Wall -c -std=c++11 

LDFLAGS  = -Wall 

LIBS  = -lGL -lGLEW -lglfw 


$(PROGNAME): $(OBJS) 
    $(CXX) $(BUILDIR)/*.o $(LDFLAGS) $(LIBS) -o $(BUILDIR)/$(PROGNAME) 

main.o: 
    $(CXX) $(CXXFLAGS) $(INCDIR) main.cpp -o $(BUILDIR)/main.o 

parking_car.o: 
    $(CXX) $(CXXFLAGS) $(INCDIR) parking_car.cpp -o $(BUILDIR)/parking_car.o 

parking_lot.o: 
    $(CXX) $(CXXFLAGS) $(INCDIR) parking_lot.cpp -o $(BUILDIR)/parking_lot.o 

shader.o: 
    $(CXX) $(CXXFLAGS) $(INCDIR) shader.cpp -o $(BUILDIR)/shader.o 

shader_manager.o: 
    $(CXX) $(CXXFLAGS) $(INCDIR) shader_manager.cpp -o $(BUILDIR)/shader_manager.o 


.PHONY: clean 

clean: 
    rm $(BUILDIR)/*.o $(BUILDIR)/$(PROGNAME) 

同樣,這個工程,我預期,但我想擺脫手動指定目錄($(BUILDIR)/someobject.o)每個.o文件將

我試過的,而不是重複的線路,這上述

$(OBJS): 
     $(CXX) $(CXXFLAGS) $(INCDIR) $(SRC) -o $(patsubst %, $(BUILDIR)/%, $(OBJS)) 

,但它給了一個錯誤的所有構建/ *。Ø

沒有這樣的文件或目錄

爲什麼它不工作?

回答

2

由於編譯器不知道要分別編譯所有源文件),所以嘗試合併所有目標文件規則失敗。

我們先從對象文件規定:

main.o: 
    $(CXX) $(CXXFLAGS) $(INCDIR) main.cpp -o $(BUILDIR)/main.o 

... 

然後我們意識到,這些規則不建什麼他們要求建立;此規則聲稱構建main.o,但它實際上構建了build/main.o。這將在以後造成麻煩,所以我們解決它:

$(BUILDIR)/main.o: 
    $(CXX) $(CXXFLAGS) $(INCDIR) main.cpp -o $(BUILDIR)/main.o 

... 

然後,我們發現,我們忘了告訴製作約files--做不知道,如果main.cpp已經改變了它應該重建這個目標的前提來源。因此,我們糾正:

$(BUILDIR)/main.o: main.cpp 
    $(CXX) $(CXXFLAGS) $(INCDIR) main.cpp -o $(BUILDIR)/main.o 

... 

然後我們使用automatic variables減少冗餘:

$(BUILDIR)/main.o: main.cpp 
    $(CXX) $(CXXFLAGS) $(INCDIR) [email protected] -o [email protected] 

... 

然後,我們注意到,所有這些目標文件建立的規則有完全一樣的命令,因此我們結合他們進入一個pattern rule

$(BUILDIR)/%.o: %.cpp 
    $(CXX) $(CXXFLAGS) $(INCDIR) [email protected] -o [email protected] 

(你可以把它們放入一個靜態方式規則,但是這是ENO唉一天)

編輯:

我們還必須改變PROGNAME規則給它正確的名稱和先決條件,並使用自動變量:

$(BUILDIR)/$(PROGNAME): $(addprefix $(BUILDIR)/, $(OBJS)) 
    $(CXX) $^ $(LDFLAGS) $(LIBS) -o [email protected] 
+0

首先感謝您的幫助。 ..但是當我做$(BUILDIR)/main.o時,它不會將輸出對象放在build目錄中(而是用.cpp文件代替),而如果沒有它,爲什麼它會這樣呢?我必須得到所有的。o並且可以在同一個目錄中執行 – ampawd

+0

@ampawd:我犯了一個小錯誤(寫'BUILDDIR'而不是你的'BUILDIR')和一個主要錯誤(忘記更正'PROGNAME'規則,我會編輯它,如果它仍然沒有沒有工作,讓我知道,我們會一步一步通過它。 – Beta