I want the build rule to be triggered by the include directive if the include target is obsolete or does not exist.
Currently, the make file looks like this:
program_NAME := wget++ program_H_SRCS := $(wildcard *.h) program_CXX_SRCS := $(wildcard *.cpp) program_CXX_OBJS := ${program_CXX_SRCS:.cpp=.o} program_OBJS := $(program_CXX_OBJS) DEPS = make.deps .PHONY: all clean distclean all: $(program_NAME) $(DEPS) $(program_NAME): $(program_OBJS) $(LINK.cc) $(program_OBJS) -o $(program_NAME) clean: @- $(RM) $(program_NAME) @- $(RM) $(program_OBJS) @- $(RM) make.deps distclean: clean make.deps: $(program_CXX_SRCS) $(program_H_SRCS) $(CXX) $(CPPFLAGS) -MM $(program_CXX_SRCS) > make.deps include $(DEPS)
The problem is that the include directive appears to make make.deps before the rule, which actually means that make either does not get a list of dependencies if make.deps does not exist or always gets make.deps from the previous assembly rather than current.
For instance:
$ make clean $ make makefile:32: make.deps: No such file or directory g++ -MM addrCache.cpp connCache.cpp httpClient.cpp wget++.cpp > make.deps g++ -c -o addrCache.o addrCache.cpp g++ -c -o connCache.o connCache.cpp g++ -c -o httpClient.o httpClient.cpp g++ -c -o wget++.o wget++.cpp g++ addrCache.o connCache.o httpClient.o wget++.o -o wget++
Edit
I read the docs for the include directive , and it looks like if the inclusion target does not exist, it will continue processing the parent makefile trying to build the target, but I donβt quite understand how it works:
If the included makefile cannot be found in any of these, a warning message appears, but it is not an immediate fatal error; processing of the makefile containing the inclusion continues. Once it has finished profiles, make try to redo everything that is outdated or does not exist. See How Makefiles Redesigned. Only after that I tried to find a way to redo the makefile and failed to diagnose the missing makefile as a fatal error.
ANSWER
This is a modification of the answer I accepted. The only thing that wasn't there was that the dependency files are also source dependent and will not be restored unless they are added to the deps files that are included:
%.d: $(program_CXX_SRCS) @ $(CXX) $(CPPFLAGS) -MM $*.cpp | sed -e ' s@ ^\(.*\)\.o:@\1.d \1.o:@' > $@
sed adds the .d file .d at the beginning of each dependency line as follows:
foo.d foo.o: foo.cpp foo.h bar.h baz.h
I got an idea from this amazing article about the dangers of recursive make:
Recursive analysis is considered malicious
I also add the following to the makefile:
clean_list += ${program_SRCS:.c=.d}