mhm
mhm

Reputation: 313

Need help understanding makefile pattern rule % : %.o

I want to change this makefile into something simpler using pattern rules I read about in a book:

VPATH = src
CPPFLAGS = -I include

main.o: main.cpp
    g++ $(CPPFLAGS) $<
TwoDimensionalShape.o: TwoDimensionalShape.cpp
    g++ -c $(CPPFLAGS) $<
Square.o: Square.cpp Square.h
    g++ -c $(CPPFLAGS) $<
Circle.o: Circle.cpp Circle.h
    g++ -c $(CPPFLAGS) $<
Rectangle.o: Rectangle.cpp Rectangle.h
    g++ -c $(CPPFLAGS) $<
Triangle.o: Triangle.cpp Triangle.h
    g++ -c $(CPPFLAGS) $<
ShapeStack.o: ShapeStack.cpp ShapeStack.h
    g++ -c $(CPPFLAGS) $<
ScreenManager.o: ScreenManager.cpp ScreenManager.h
    g++ -c $(CPPFLAGS) $<
ScreenState.o: ScreenState.cpp ScreenState.h
    g++ -c $(CPPFLAGS) $<
SquareState.o: SquareState.cpp SquareState.h
    g++ -c $(CPPFLAGS) $<
CircleState.o: CircleState.cpp CircleState.h
    g++ -c $(CPPFLAGS) $<

After reading the book I can write the above using pattern rules like this. But I don't understand how it is working:

#source files are in "src" folder.
VPATH = src
#header files are in "include" folder.
CPPFLAGS = -I include -Wall

all: main.o TwoDimensionalShape.o Square.o Circle.o Rectangle.o Triangle.o ShapeStack.o ScreenManager.o ScreenState.o SquareState.o CircleState.o
    g++ $(CPPFLAGS) $^

%.o: %.cpp
    g++ -c $(CPPFLAGS) $<

%: %.o
    g++ $<

This makefile is correct however I don't understand how it is working.

  1. If I change for example 2 source files, how does this makefile understand to only compile the changed two source files and not all of source files?
  2. In the book I read, example was about C not C++ and last line was %: %.c. Then why is my line which is %: %.o working? Shouldn't it be %: %.cpp?

Upvotes: 1

Views: 720

Answers (1)

Klaus
Klaus

Reputation: 25593

This makefile is correct however I don't understand how it is working.

If your new Makefile is a replacement for the old one, it is definitely NOT working.

In the "old" one you have e.g.

ShapeStack.o: ShapeStack.cpp ShapeStack.h

which tells that ShapeStack.o depends on the .cpp and header file. Your new Makefile did not have any dependencies to other files which will result in a lot of trouble. Simply touch one of your headers and type make. Nothing will happen!

So at minimum you have to introduce your source file dependecies, maybe manual as in your old makefile or with some more automatism which uses the dependency check from the compiler, using gcc it is with "gcc -MM".

For getting automated prerequisites see https://www.gnu.org/software/make/manual/html_node/Automatic-Prerequisites.html

And using vpath can result in a lot of trouble. There are some articels, e.g.: http://make.mad-scientist.net/papers/how-not-to-use-vpath/

Some example Makefiles can be found already here: minimum c++ make file for linux

Upvotes: 3

Related Questions