Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

c++

makefile

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?

like image 637
Magnus Avatar asked Dec 25 '22 01:12

Magnus


1 Answers

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.

like image 159
taskinoor Avatar answered Mar 01 '23 23:03

taskinoor