Reputation: 479
I have (old suffix type) rules inside my Makefile for .c and .o files. The problem is that when i run make all
those rules are not used and instead the implicit rules are used.
If i run make all -r
then it will tell me make: *** No rule to make target...
which is expected since i have intentionally not added explicit rules for program1...3.
In order to fix this issue i can add explicit rules for program1...3:
program1: program1.o
So a solution is not what i am after here. Just an explanation.
all: program1 program2 program3
.o:
@echo What is going on 1
$(CC) $(LIBS) $(LDFLAGS) $< -o $(OUT)/$@
.c.o:
@echo What is going on 2
$(CC) -c $(CFLAGS) $(IFLAGS) $(CPPFLAGS) $< -o $@
Why does make use implicit rules in the current case even though i have explicitly written the rules for .c and .o files?
Upvotes: 0
Views: 254
Reputation: 4261
When running make
without -r
option, the built-in rule comes in place:
%: %.c
# recipe to execute (built-in):
$(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o $@
This can be verified with make -p
:
...
program1: program1.c
# Command line target.
# Implicit rule search has been done.
# Implicit/static pattern stem: 'program1'
# Last modified 2019-11-19 14:28:03.247550778
# File has been updated.
# Successfully updated.
# automatic
# @ := program1
# automatic
# % :=
# automatic
# * := program1
# automatic
# + := program1.c
# automatic
# | :=
# automatic
# < := program1.c
# automatic
# ^ := program1.c
# automatic
# ? := program1.c
# variable set hash-table stats:
# Load=8/32=25%, Rehash=0, Collisions=1/21=5%
# recipe to execute (built-in):
$(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o $@
...
This rule is selected over chain of implicit rules %.c -> %.o -> %
as documented:
There are some special implicit rules to optimize certain cases that would otherwise be handled by rule chains. For example, making
foo
fromfoo.c
could be handled by compiling and linking with separate chained rules, usingfoo.o
as an intermediate file. But what actually happens is that a special rule for this case does the compilation and linking with a singlecc
command. The optimized rule is used in preference to the step-by-step chain because it comes earlier in the ordering of rules.
Now, when you disable built-in rules with -r
, old-fashioned rules that you use are also disabled, due to .SUFFIXES
being empty, as documented:
Suffix rule definitions are recognized by comparing each rule’s target against a defined list of known suffixes. When
make
sees a rule whose target is a known suffix, this rule is considered a single-suffix rule.The known suffixes are simply the names of the prerequisites of the special target
.SUFFIXES
.The ‘
-r
’ or ‘--no-builtin-rules
’ flag causes the default list of suffixes to be empty.
Upvotes: 2
Reputation: 99084
Your question omits some details, but I'll go out on a limb.
You have written a rule for the target .o
, and a pattern rule for targets of the pattern "%.o". But you are not asking make to build .o
or program1.o
, you are asking it to build program1
. Had you examined the results of running Make, you would have noticed that there is no object file involved.
Upvotes: 0