BadCash BadCash - 1 year ago 45
C++ Question

Make always runs for target "all", even when there's nothing to update

I have these files

  • Test.cpp

  • Point.h

  • Point.cpp

  • Triangle.h

  • Triangle.cpp

and I want to have a makefile that allows me to build each of the classes
separately by issuing
make Point
make Triangle
when needed (either the header or source files have changed).
make all
should compile everything and build the output program
if needed.

This is what I have come up with so far:

CXXFLAGS=-std=c++11 -Wall -pedantic
OBJS=Test.o Point.o Triangle.o

all : $(OBJS)
$(CXX) $(CXXFLAGS) $(OBJS) -o Test

Point.o : Point.cpp Point.h
$(CXX) $(CXXFLAGS) -c Point.cpp

Point : Point.o

Triangle.o : Triangle.h Triangle.cpp Point.h
$(CXX) $(CXXFLAGS) -c Triangle.cpp

Triangle : Triangle.o

\rm *.o Test

.PHONY : Point Triangle

It seems to work, but the problem is that when i run
make all
(or just
) multiple times it runs the command even if nothing has changed, giving the following output:

g++ -std=c++11 -Wall -pedantic Test.o Point.o Triangle.o -o Test

I want it to say something like "Nothing to be done for 'all'." or something similar, just like it does for the other targets. What am I missing?

Answer Source

all knows nothing about the output file Test. Since it doesn't know about any specific target file, it can't compare the timestamp of target and dependencies. That's why it's always running the command. You need to tell make that by all you actually meant to generate the file Test. You can do something like this:

all : Test

Test : $(OBJS)
    $(CXX) $(CXXFLAGS) $(OBJS) -o Test

Apart from this issue you also need to specify rule for Test.o.