I'm trying to port linux kernel's kconfig util to my product
while compiling I got next error:
make[6]: *** No rule to make target `zconf.tab.c', needed by `zconf.tab.o'. Stop.
I found next rule in Makefile.lib for this file
$(obj)/%: $(src)/%_shipped
$(call cmd,shipped)
It looks ok for me and it just works in kernel but not in my product.
Then I added another rule right after previous one.
$(obj)/%c: $(src)/%c_shipped
$(call cmd,shipped)
And now it works just fine.
Can someone explain me what's wrong with original rule?
In my case obj=.
and src=.
(both = dot). Current dir contains appropriate *_shipped
file.
My guess is that $(obj)/%: $(src)/%_shipped
qualifies as a match-anything pattern rule. (The manual doesn't mention how targets and prerequisites with with directory components are handled, but it would make sense.)
Note the following in the manual:
A non-terminal match-anything rule cannot apply to a file name that indicates a specific type of data. A file name indicates a specific type of data if some non-match-anything implicit rule target matches it.
Since there are already built-in implicit rules for creating .c
files (using parser generators for example), the match-anything rule is never considered.
The reason the error doesn't happen for the kernel makefiles is that they run make
with -r
, which eliminates built-in implicit rules. It's done in the top-level makefile by setting the MAKEFLAGS
variable:
# Do not use make's built-in rules and variables
# (this increases performance and avoids hard-to-debug behaviour);
MAKEFLAGS += -rR
As a simple experiment, I created a file test.c_foo and the following makefile:
MAKEFLAGS += -r
%: %_foo
@echo building
make test.c
without the first line gives
make: *** No rule to make target 'test.c'. Stop.
With the first line, it prints "building" instead.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With