In an effort to replace the mess of independent makefiles we inherited from another project with something that actually uses make
as it should be (as noted in this question, I've come across a rather unusual situation in which gmake 3.81
ignores files it cannot generate nor can find.
Here's a short sample file that demonstrates the problem:
# Remove ALL default rules
.SUFFIXES:
(%): %
%.out: %
%.c: %.w %.ch
%.tex: %.w %.ch
%:: %.v
%:: RCS/%,v
%:: RCS/%
%:: s.%
%:: SCCS/s.%
SOURCES = a.c b.c
OBJS = $(SOURCES:%.c=%.o)
DEPFILES = $(SOURCES:%.c=%.c.d)
EXE = a
.PHONY: all
all: $(EXE)
$(DEPFILES): %.c.d : %.c
@echo "Determining dependencies for $(<F)"
@$(CC) -E -MM -MF$@ -MP $<
$(OBJS): %.o: %.c
@echo "Compiling $(<F)"
@$(CC) -c $< -o $@
$(EXE): $(OBJS)
@echo "Linking $(@F)"
@$(CC) $+ -o $@
# This seems to be the troublemaking line!
-include $(DEPFILES)
If one or more of the source files is missing, the corresponding .d
file is not made, as expected, but the source file is not flagged as missing. If I run this with a simple make
command, nothing is output, and the exit status is 2.
Is there any way I can work around this?
Oh, although it seems silly in this example, I do have several restrictions in this project:
- We must use
gmake 3.81
. No upgrading or patching allowed. - The full makefile builds both a debug & a release version, so dependencies are generated separately, once for all. It turned out to be simpler that way.
- Using static pattern rules seems silly here, but in the large makefile it solves many problems.
- The actual generation of dependencies is significantly more complex in the real system, using a Perl script I wrote to massage the equivalent output of the Intel compiler suite (again, a requirement) into something useful.
- I've thought about pre-testing the existence of every file, but not all of them are known until the dependency files are generated. As it stands, with just this one file and nothing else in a directory, no shell commands get executed.
This appears to be a bug in gmake 3.81 and later, related to this bug. I've reported this specific bug, as it is slightly different.
The workaround I've chosen to use is inspired by the above link, is noted below: