הלינקייה: מגזין חודשי למפתחים

רוצה לשמוע על כל האירועים, המדריכים, הקורסים והמאמרים שנכתבו החודש ?
הלינקייה הינו מגזין חופשי בעברית שמשאיר אותך בעניינים.
בלי ספאם. בלי שטויות. פעם בחודש אצלך בתיבה.

Using VPath

So far, we've been using small projects, where all the files reside within the same path. In most real world applications, this is rarely the case.

The following examples assume a Zombie farm project, with the following directory structure.

zombiefarm/makefile
zombiefarm/include/Person.h
zombiefarm/include/Zombie.h
zombiefarm/src/Main.cpp
zombiefarm/src/Person.cpp
zombiefarm/src/Zombie.cpp

Full source code is in the example zip (05_vpath).

Now, let's example some makefiles for this project.

############################################
# A simple makefile searching for all the files
# in the current working directory
 
target = zombiefarm
objects = Person.o Zombie.o Main.o
 
all: $(target)
 
$(target): $(objects)
	$(CXX) $^ -o $@
 
Person.o: Person.cpp Person.h
	$(CXX) -c $<
 
Zombie.o: Zombie.cpp Zombie.h Person.h 
	$(CXX) -c $<
 

If you try to run this fist makefile, you should encounter the error: No rule to make target. This is because make looks for the Person.cpp file in the current working directory, but cannot find it. We need some way to let make know the file is in the src directory.

The method below works, but it is tedious.(Note the -I include flag to let the compiler know where the header files are.

target = zombiefarm
objects = Person.o Zombie.o Main.o
CPPFLAGS = -I include
.PHONY: all clean
 
all: $(target)
 
$(target): $(objects)
	$(CXX) $(CPPFLAGS) $^ -o $@
 
Person.o: src/Person.cpp 
	$(CXX) $(CPPFLAGS) -c $<
 
Zombie.o: src/Zombie.cpp
	$(CXX) $(CPPFLAGS) -c $<
 
Main.o: src/Main.cpp
	$(CXX) $(CPPFLAGS) -c $<
 
clean:
	rm -f $(objects) $(target)
 

The vpath directive is a way around this limitation. It provides a way to let make know where to look for its source files. Here's an example.

Note the %.cpp means "all files ending in a .cpp"

target = zombiefarm
objects = Person.o Zombie.o Main.o
CPPFLAGS = -I include
.PHONY: all clean
 
vpath %.cpp src
 
all: $(target)
 
$(target): $(objects)
        $(CXX) $(CPPFLAGS) $^ -o $@
 
Person.o: Person.cpp
        $(CXX) $(CPPFLAGS) -c $<
 
Zombie.o: Zombie.cpp
        $(CXX) $(CPPFLAGS) -c $<
 
Main.o: Main.cpp
        $(CXX) $(CPPFLAGS) -c $<
 
clean:
        rm -f $(objects) $(target)
 
course: