Reputation: 177
I have a makefile of this kind:
program: \
a/a.o \
b/b.o
$(CXX) $(CXXFLAGS) -o program \
a/a.o \
b/b.o
a.o: \
a/a.cpp \
a/a.h
$(CXX) $(CXXFLAGS) -c a/a.cpp
b.o: \
b/b.cpp \
b/b.h
$(CXX) $(CXXFLAGS) -c b/b.cpp
So in the directory of the makefile I have two subdirectories a and b that contain respectively a.h, a.cpp and b.h, b.cpp. The problem is that if I modify a .cpp file, issuing a make rebuilds the target program but if I modify an .h file make do not rebuilds anything but says
make: `program' is up to date.
I can't understand why, because the .h files are in the prerequisites line along with the .cpp files. Interestingly, if I issue a make on an object file target like
$ make a.o
instead, the modifications to a/a.h are detected and the target a/a.o is rebuild. Where is the problem?
Upvotes: 1
Views: 396
Reputation: 17383
The subdirectories that you added to the question later are causing the problem indeed. The target program
depends on a/a.o
and b/b.o
, but there are no explicit rules to make those to .o
files -- only the targets a.o
and b.o
are present but those are not in the subdirectories.
Therefore, make
will look for implicit rules to build a/a.o
and b/b.o
. That rule does exist, you will see it being found when you run make -d
. That implicit rule depends on a/file_a.cpp
only, not on a/file_a.h
. Therefore, changing a/file_a.cpp
will make a/a.o
out of date according to that implicit rule, whereas a/file_a.h
will not.
For your reference, the make User's Manual has a section Catalogue of Implicit Rules. That also explains that you can use the argument --no-builtin-rules
to avoid that implicit behavior. If you use that, you will see that make
can not find any rules to make a/a.o
and b/b.o
.
Finally, running make a.o
will run the recipe for the target a.o
as defined in your makefile. That target does have a/a.h
as its prerequisite so any change to that file will result in a recompile. But essentially, that has nothing to do with the target program
, which has different prerequisites.
Upvotes: 2