GNU Make - terminal rules and keyword “null”

2019-08-26 19:56发布

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条回答
兄弟一词,经得起流年.
2楼-- · 2019-08-26 20:23

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.

查看更多
登录 后发表回答