bug-make
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[bug #56892] toxic combination of -include and match-anything rules


From: David Boyce
Subject: [bug #56892] toxic combination of -include and match-anything rules
Date: Sat, 14 Sep 2019 16:28:33 -0400 (EDT)
User-agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/77.0.3865.75 Safari/537.36

URL:
  <https://savannah.gnu.org/bugs/?56892>

                 Summary: toxic combination of -include and match-anything
rules
                 Project: make
            Submitted by: boyski
            Submitted on: Sat 14 Sep 2019 08:28:32 PM UTC
                Severity: 3 - Normal
              Item Group: Bug
                  Status: None
                 Privacy: Public
             Assigned to: None
             Open/Closed: Open
         Discussion Lock: Any
       Component Version: 4.2.1
        Operating System: POSIX-Based
           Fixed Release: None
           Triage Status: None

    _______________________________________________________

Details:

I'm not saying this is a bug necessarily but want to submit it for some sort
of resolution. I an into an infinite loop situation recently. On my advice, in
a very old and complex recursive makefile suite (not of my design or under my
ownership) a co-worker added a construct like the following:

-include foobar.mk
foobar ?= XYZ

The idea is that foobar.mk would be a one-line include file which assigns the
"foobar" variable if it exists and if not we fall back to the default value
"XYZ". This is simple and solved his problem in unit testing but when plugged
into the large old suite it resulted in an infinite loop.

The reason is twofold: (a) if an included makefile doesn't exist make will try
to run a recipe to create it and (b) somewhere deep in this makefile suite was
a match-anything rule. From here it's obvious: make went looking for a recipe
that claimed to be able to make foobar.mk, landed on the match-anything rule
which does a recursive make invocation (and does not create foobar.mk), and
we're off to the races with an infinite make loop.

The situation is illustrated by the following test file:

$ cat Makefile
.PHONY: all
all:
        @:$(info making $@)

%:
#       @test -f nosuchfile.mk
        $(MAKE) $@

#-include nosuchfile.mk

As it stands this works fine:

$ make
making all

If the -include line is enabled the infinite loop happens, but if the test -f
line is also uncommented things work correctly again.

My first thought is that it makes no sense to invoke a recipe to create a
nonexistent file included via -include because the whole point of -include is
to say "I know this file may not exist and that's ok". However, the
documentation says of -include that it:

"... acts like include in every way except that there is no error [...] if any
of the filenames [...] do not exist or cannot be remade."

I guess the "or cannot be remade" is a strong implication that -include files
are subject to remaking so maybe it would hard to "fix" this for compatibility
reasons? And of course there's a difference between a file being out of date
and not existing and it makes perfect sense to want to update a -included file
if it exists.

However, I still think that in the special case where foobar.mk does not exist
and is included with -include the remake attempt should be elided and the
inclusion silently skipped. Whether that's too much of a compatibility break
is a valid question though.

But even stepping back from those details, with either "include" or
"-include", why should make continue if it ran the recipe and the recipe did
not in fact create the file as it claimed it would? In other words, why not do
a check for existence after running the remake recipe (as illustrated in the
test case)? It seems to me that dying with "no such file or directory" would
be preferable to allowing an infinite loop, and furthermore I think this could
be added without breaking (documented) compatibility.  AFAICT the manual
discusses only situations where the included file "cannot be remade". 
Currently "remaking" seems to be a synonym for "running the recipe which
claims to make it" but tightening that definition to to require that the
recipe actually creates the file seems both more robust and entirely
compatible, not to mention intuitive.

Thus I suggest one or both of these minor tweaks:

1. Fail (with include) or continue (with -include) when, after running the
remake recipe, the file does not exist.

2. Ignore (do not attempt to make) a file included by -include if it does not
exist at all. But if if does exist, go ahead and try to update it.




    _______________________________________________________

Reply to this item at:

  <https://savannah.gnu.org/bugs/?56892>

_______________________________________________
  Message sent via Savannah
  https://savannah.gnu.org/




reply via email to

[Prev in Thread] Current Thread [Next in Thread]