1
votes

My Makefile contains an implicit rule override in the form of an explicit rule definition. However, make still invokes the default implicit rule.

This is on RHEL 6.3, GNU Make Version 3.81.

CPPFLAGS = -Wall -O2

DEPDIR = .d
DEPFLAGS = -MT "$@ $(DEPDIR)/$*.d" -MMD -MP -MF $(DEPDIR)/$*.d

SRCS = $(wildcard *.cpp)
OBJS = $(SRCS:.cpp=.o)

%.o: %.cpp $(DEPDIR)/%.d
        g++ -c $< $(CPPFLAGS) $(DEPFLAGS) -o $@

$(DEPDIR)/%.d: $(DEPDIR) ;

$(DEPDIR):
        mkdir -p $@

include $(wildcard $(DEPDIR)/*.d)

.PHONY: clean clobber
clean:
        rm -f *.o
        rm -rf $(DEPDIR)

Invocation of 'make' outputs this:

[tlytle@tlytle-dev]$ make
g++  -Wall -O2  -c -o my_source.o my_source.cpp

Why is make invoking the default implicit rule for %.o files and not my explicit rule for %.o files defined in my Makefile?

2
I don't see any explicit rule, and it's not possible for there to be an explicit rule for a pattern (by definition). Maybe you are misusing the terms "implicit" and "explicit" as they apply to make? But without understanding what you mean there's no way we can understand your question. - MadScientist
Oh, maybe you mean default rules where you are using implicit rules? That seems likely. - MadScientist

2 Answers

3
votes

You are not overriding the default rule for building .o files from .cpp files. In order to override it you'd need to define a new rule with identical target and prerequisites; your implicit rule has extra prerequisites, so you're just adding a new implicit rule that could build a .o file.

The rules for choosing implicit rules when multiple ones may match can be confusing.

The simplest thing to do is delete the builtin rule so that it's not available to be considered. You can do this by defining an implicit rule with the same target and prerequisites as the builtin rule, but no recipe:

%.o : %.cpp

Now make will have no choice but to use your implicit rule.

Note that GNU make 3.81 is really old. In newer versions of GNU make you can delete all the builtin rules to start by adding this to your makefile:

MAKEFLAGS += -r
0
votes

I'd start from trying to run it with --no-builtin-rules to prove/disprove the theory about implicit/default (both are legit terms) rules being involved.

The manual says, that for an override to work both the target and prerequisites must match, and in your case it's not. Could be that.