2017-02-13 72 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