问题
BACKGROUND
This is related to my question GNU make - transform every prerequisite into target (implicitly)
I've posted this question because it's interesting and may be useful by itself - to understand make
- and I don't want it to get lost in the "original" question.
INFO
I have a file Dummy.mk
:
%:: null
@:
null:
@:
which I pass to my make
as make all MAKEFILES=Dummy.mk
.
When I replace null
with saflkjsaflkjdsa
,
%:: saflkjsaflkjdsa
@:
saflkjsaflkjdsa:
@:
the behavior of the build was different: the rule was never executed.
The reason is because this is a "terminal rule":
One choice is to mark the match-anything rule as terminal by defining it with a double colon. When a rule is terminal, it does not apply unless its prerequisites actually exist. Prerequisites that could be made with other implicit rules are not good enough. In other words, no further chaining is allowed beyond a terminal rule.
Since saflkjsaflkjdsa
did not exist, the rule was not executed. Ok fine I understand that.
But when I set Dummy.mk
using the keyword null
%:: null
@:
null:
@:
the %::
rule does execute i.e. it captures ALL targets, filenames, etc giving me outputs of the form :2: update target <item> due to: null
where <item>
is any filename or target that make
reads in.
Since the rule is executing using null
but not with using saflkjsaflkjdsa
, make
is definitely detecting null
as "existing".
QUESTION
But then why do I still get the output :5: target 'null' does not exist
?
Is that because of the OS- or shell-level peculiarities of null
existing but not existing at the same time?
Environment
* Windows 8, 64-bit
* Make 4.2.1 (here's output of make
# GNU Make 4.2.1
# Built for Windows32
# Copyright (C) 1988-2016 Free Software Foundation, Inc.
# License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
# This is free software: you are free to change and redistribute it.
# There is NO WARRANTY, to the extent permitted by law.
find_and_set_shell() path search set default_shell = C:/Users/User1/Desktop/A/QNX_SDK/host/win32/x86/usr/bin/sh.exe
...
* Shell that make
is using internally is:
C:\Users\User1\Desktop\A\Project\bld\armle-v7\release\subProj>where sh
C:/Users/User1/Desktop/A/QNX_SDK/host/win32/x86/usr/bin/sh.exe
C:\Users\User1\Desktop\A\Project\bld\armle-v7\release\subProj>sh --help
GNU bash, version 3.1.17(1)-release-(i686-pc-msys)
Usage: sh [GNU long option] [option] ...
sh [GNU long option] [option] script-file ...
GNU long options:
--debug
--debugger
--dump-po-strings
--dump-strings
--help
--init-file
--login
--noediting
--noprofile
--norc
--posix
--protected
--rcfile
--restricted
--verbose
--version
--wordexp
Shell options:
-irsD or -c command or -O shopt_option (invocation only)
-abefhkmnptuvxBCHP or -o option
Type `sh -c "help set"' for more information about shell options.
Type `sh -c help' for more information about shell builtin commands.
Use the `bashbug' command to report bugs.
回答1:
Is that because of the OS- or shell-level peculiarities of null existing but not existing at the same time?
Since you didn't specify which OS or shell you're using, it's impossible for us to say. All I can say is that I tried to replicate your problem on my GNU/Linux system and couldn't: on my system no targets were built in either case (using null
or saflkjsaflkjdsa
made no difference)
My suspicion is you're using Windows; I have a vague recollection that null
is special somehow on Windows. But, I don't do Windows so I can't say for sure.
来源:https://stackoverflow.com/questions/38250056/gnu-make-terminal-rules-and-keyword-null