Implict rule cancellation in Makefile - makefile

I have come across the following line in U-boot Makefile ( https://github.com/siemens/u-boot/blob/master/Makefile#L128 ) with comment "Cancel implicit rules on top Makefile".
Can you help me to understand the following line, how/what will happen while executing the following line by make utility.
$(CURDIR)/Makefile Makefile: ;

See How Makefiles Are Remade:
If you know that one or more of your makefiles cannot be remade and you want to keep make from performing an implicit rule search on them, perhaps for efficiency reasons, you can use any normal method of preventing implicit rule look-up to do so. For example, you can write an explicit rule with the makefile as the target, and an empty recipe.
And that is exactly what $(CURDIR)/Makefile Makefile: ; rule does - it has an empty recipe.

Related

GNU Make: Ensure existence of prerequisite and disable implicit rule search

Question:
How can I disable implicit rule searches on a prerequisite while still ensuring that the prerequisite actually exists?
Background:
Consider the following initial Makefile:
b: a
#echo MAKING B
cp a b
a is a file which is required in order to make b. If the file a exists, make b runs successfully. If it doesn't exist, we obtain the following error:
make: *** No rule to make target `a', needed by `b'. Stop.`
This is exactly what we expected, however on inspecting the output of make --debug=a b, we see that even when a exists, make is searching through pre-defined implicit rules fitting a in order to see whether it can be re-made. For example, if the file a.c happened to exist, then make would try to compile a.c to produce the file a. To prevent this, we define an explicit rule for a with an empty recipe. This gives us the updated Makefile:
a: ;
b: a
#echo MAKING B
cp a b
The problem now is that the recipe for make b runs even if a does not exist, which results in a failure. Is there any other way to indicate that a should exist, while not searching for implicit rules to build a? I would like to do this without giving a recipe for a which checks its existence.
I'll try to sum up state of our discussion so far. Perhaps someone still pop's up with another/better insight.
Besides the option also mentioned in the question itself (see bellow for explainer on latest iteration for this approach):
a:
$(error missing file "$#")
b: a
#echo MAKING B
cp a b
In theory it should be possible to disable implicit pattern rule altogether or for specific (set) of target(s) by either defining a no recipe target rule (% : %.c) or defining a static pattern rule (a: % : %.c). Nonetheless the resulting behavior, in case there is an a.c file, seems to be the same as with an empty rule for a:. I.e. make b just proceeds without file a being present (and we'd later fail trying to access it).
Since at least some of the implicit rule seem to be implemented as suffix rules, it's possible to disable consideration of inputs like a.c by purging list of default suffices:
.SUFFIXES:
Or inhibit use of implicit built-in rules altogether by invoking make with -r (or --no-builtin-rules) option. These however are rather heavy handed as they impact processing of all the rules across the Makefile.
To work the comment in:
as mentioned disabling couple of the built in rules for C compilation would appear to yield the desired result, namely:
% : %.c
% : %.o
Would result with a.c present and no a in make: *** No rule to make target 'a', needed by 'b'. Stop.
However (like -r) it's rather intrusive as in all other targets relying on the implicit rule would be impacted. While at the same time it's not as very far reaching, because it does not cover other cases like a.C, a.cpp, a,v,...
Static rule should be able to replace pattern rules where applicable (a more specific rule being applied over the more generic one when matching). But indeed limiting its to a single target does basically put it on par with just a specific a: rule.
I am actually not sure what the rest of the tree looks like and what all possible build steps could occur. With current understanding I would still gravitate to explicit target with file existence check should files with colliding names be a possibility and concern.
Explanation for the latest version of simple failing rule:
As #Stein followed up on the topic, he actually very helpfully pointed out: Simple (always) failing rule for "building" a is perfectly sufficient. If a file of that name (a) exists, the rule for target a never gets to run its recipe. For the case the file is not there, we can just have a recipe that fails with an error message.

a surprising (?) behaviour of GNU Make when using ``%`` as target

Consider the following Makefile
foo:
#echo '$#'
test:
#echo '$#'
#echo '---'
# Catch-all target
%: test
#echo '+++'
#echo '$#'
When issuing make bar the following is the console output:
$ make bar
test
---
+++
Makefile
+++
bar
I would like to understand the origin of Makefile which shows it is received as argument at some point, and also how to get rid of it in such a scheme. This is using
GNU Make 4.1
Built for x86_64-apple-darwin13.4.0
GNU make treats the makefile itself as a target that needs to be updated. See How Makefiles Are Remade:
... after reading in all makefiles, make will consider each as a goal target and attempt to update it. If a makefile has a rule which says how to update it (found either in that very makefile or in another one) or if an implicit rule applies to it (see Using Implicit Rules), it will be updated if necessary...
If you know that one or more of your makefiles cannot be remade and you want to keep make from performing an implicit rule search on them, perhaps for efficiency reasons, you can use any normal method of preventing implicit rule look-up to do so. For example, you can write an explicit rule with the makefile as the target, and an empty recipe (see Using Empty Recipes).
Hence, the catch-all-target % is used to update Makefile.
Makefiles often do not have to be updated, so it is customary to add an empty rule for that:
Makefile : ;

Rule with wildcard to depend on other rules [duplicate]

I'm observing an interesting behavior of make and I wonder if there is a reasonable explanation to it besides a bug in gmake.
Let's say we have the following in makefile:
%-animal:
echo "$* is an animal"
%-fox: %-fox-animal
%-wolf: %-wolf-animal
The difference between the last two targets is that "%-wolf" does not have any recipe, and "%-fox" has an empty recipe (i.e. just a line with a tab at the beginning).
When we try to execute the rules, here's what happens:
[root#cv19 tmp]# make freddy-animal
echo "freddy is an animal"
freddy is an animal
[root#cv19 tmp]# make freddy-wolf
make: *** No rule to make target `freddy-wolf'. Stop.
[root#cv19 tmp]# make freddy-fox
echo "freddy-fox is an animal"
freddy-fox is an animal
i.e.the pattern rule that has a recipe (although an empty one) works, the one that doesn't does not. Am I missing something in the way it's supposed to work?
Pattern rules with no recipes at all are documented as meaning something quite different from those providing a recipe, even an empty one. Instead they cancel any pre-existing implicit rule:
You can cancel a built-in implicit rule by defining a pattern rule with the same target and prerequisites, but no recipe.
Thus your "%-wolf" pattern actually serves to cancel any existing implicit rule for %-wolf-animal -> %-wolf. And there wasn't one anyway.

How to makefile parse

At the make manual said:
During the first phase it reads all the makefiles, included makefiles,
etc. and internalizes all the variables and their values, implicit and
explicit rules, and constructs a dependency graph of all the targets
and their prerequisites.
I don't understand how the dependency graph constructed? Consider the following makefile:
%.o: %.z
echo This is overriden implicit rule
default: foo.o
clean:
rm -f fmake test_second
%.o: %.c
echo This is customized implicit rule
After make command
echo This is customized implicit rule
This is customized implicit rule
is displayed, but I'm expexted that
echo This is overriden implicit rule
This is overriden implicit rule
will be, because in make rule only overrides if both the target and the prerequisite patterns match. In this case I think that %.o: %.z implicit rules matched to pattern already.
I've been doing a lot of work with Makefiles in a very, very large codebase for the last year or so. I am heartily sick of make(1s)!
The answer, in general, is "last declaration wins". You also have to contend
with the default make suffix rules (on Solaris these are found in /usr/share/lib/make/make.rules).
So if you want your overridden implicit rule to stand, place it last in the
Makefile hierarchy. If you want to flush the suffixes list, you can do either
or both of
1 add a .SUFFIXES:
line to your Makefile,
2 call make with -r
in MAKEFLAGS (env var) or on the make invocation command line.
[Also, you can prepend "#" to the start of your command to just see the output
of it, rather than the
echo [output goes here]
as well as the actual
[output goes here]
You could also gather insight by using one of the debugging options that
make(1s) allows. On Solaris, that's -d, -dd, -D or -DD. For GNU Make, it's
-d or --debug. Caution, though, dump the output from the command to a file,
because there is a lot of it.
You might want to read http://freecode.com/articles/what-is-wrong-with-make, as a piece of on-the-side illumination.

makefile pattern rules without recipes

I'm observing an interesting behavior of make and I wonder if there is a reasonable explanation to it besides a bug in gmake.
Let's say we have the following in makefile:
%-animal:
echo "$* is an animal"
%-fox: %-fox-animal
%-wolf: %-wolf-animal
The difference between the last two targets is that "%-wolf" does not have any recipe, and "%-fox" has an empty recipe (i.e. just a line with a tab at the beginning).
When we try to execute the rules, here's what happens:
[root#cv19 tmp]# make freddy-animal
echo "freddy is an animal"
freddy is an animal
[root#cv19 tmp]# make freddy-wolf
make: *** No rule to make target `freddy-wolf'. Stop.
[root#cv19 tmp]# make freddy-fox
echo "freddy-fox is an animal"
freddy-fox is an animal
i.e.the pattern rule that has a recipe (although an empty one) works, the one that doesn't does not. Am I missing something in the way it's supposed to work?
Pattern rules with no recipes at all are documented as meaning something quite different from those providing a recipe, even an empty one. Instead they cancel any pre-existing implicit rule:
You can cancel a built-in implicit rule by defining a pattern rule with the same target and prerequisites, but no recipe.
Thus your "%-wolf" pattern actually serves to cancel any existing implicit rule for %-wolf-animal -> %-wolf. And there wasn't one anyway.

Resources