BadCash BadCash - 2 months ago 6
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
Point
and
Triangle
separately by issuing
make Point
or
make Triangle
when needed (either the header or source files have changed).
make all
should compile everything and build the output program
Test
if needed.

This is what I have come up with so far:

CXX=g++
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


clean:
\rm *.o Test


.PHONY : Point Triangle


It seems to work, but the problem is that when i run
make all
(or just
make
) 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

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.

Comments