bugmake - Bugs: bug #46013, Command overrides added to...


bug #46013: Command overrides added to MAKEOVERRIDES are lost if there were no overrides in the command line

Submitted by:  Rici Lake <rici>
Submitted on:  Mon 21 Sep 2015 02:59:44 AM UTC  
Severity:  3 - Normal Item Group:  Bug
Status:  Fixed Privacy:  Public
Assigned to:  None Open/Closed:  Closed
Component Version:  4.1 Operating System:  POSIX-Based
Fixed Release:  SCM Triage Status:  None

Add a New Comment (Rich Markup)

You are not logged in

Please log in, so followups can be emailed to you.


Sun 19 May 2019 11:51:34 PM UTC, comment #4: 

Fix for this pushed.

Note, it's not as simple as the change suggested below.  With just that change, extraneous " -- " tokens are added to recursive makefiles when there are no variable overrides which causes regression tests to fail (and other issues as well)

Paul D. Smith <psmith>
Project Administrator
Fri 10 May 2019 03:19:53 PM UTC, comment #3: 

It's disappointing that nothing seems to have happened to this bug since the original report 3.5 years ago. I ran into the same problem and it cost me quite a bit of time to understand what was going on (and would have costed even more if I didn't find this bug by searching the web, thanks a lot Rici for debugging this and writing it up!).

As Rici's report also included a trivial patch fixing the problem, what delays applying it? Surely the fact that setting MAKEOVERRIDES  doesn't work unless the variable is really defined on make command line is a bug and can't be intentional, can it?

Vadim Zeitlin <zeitlin>
Wed 30 Sep 2015 07:28:24 PM UTC, comment #2: 

I have a hard time seeing the relationship of Comment #1 with the bug report.

I am not suggesting that override should automatically be passed on to submakes. It is precisely for this reason that I expect to be able to pass them on by way of changes to MAKEFLAGS or MAKEOVERRIDES. As I read section 5.7.3 (Communicating Options to a Sub-make) of the manual, the point of allowing changes to MAKEFLAGS is to pass these changes to submakes, and this works if there is at least one override on the original command line.

The inconsistency alone should be sufficient to qualify it as a bug.

I completely agree that the fact that override by itself is not sufficient to automatically pass variables to submakes is expected behaviour. Perhaps the comment was intended to apply to some other bug report.

Rici Lake <rici>
Mon 28 Sep 2015 04:59:35 PM UTC, comment #1: 

Simplified example:

exec gmake --warn-undefined-variables -f "$0" "$@"

$(warning Global 1: TEST == ${TEST})
# I took the liberty of adding "export"
export override TEST :=${TEST}.
$(warning Global 2: TEST == ${TEST})

1 2:
$(warning From target $@: TEST == ${TEST})
$(if $(filter 1,$@),@${MAKE} -f $(firstword ${MAKEFILE_LIST}) 2

# Executed like this you get ".." in the 2nd invocation:
~ example.sh
# Executed like this the command-line variable cannot be
# overridden for recursive make calls; TEST is always "x."
~ example.sh TEST=x
# Executed like this you get "x.." in the 2nd invocation:
~ TEST=x example.sh
~ example.sh -e TEST=x

I'm of the opinion this /not/ unexpected behavior.  The documentation says nothing about overriding for recursive make invocations when you use the "override" keyword.  Furthermore, it's probably better practice to explicitly pass along a MAKE variable to recursive make instances instead of it being implicit, otherwise tracking down a bug related to it could be more problematic.

Mon 21 Sep 2015 02:59:44 AM UTC, original submission:  

The motivation for the `override` declaration is to allow appending a value to a variable set as a command-line override. For example:

    # Example taken from the gnu make manual, section 6.7
    override CFLAGS += -g

For recursive makes, it is at least possible that it will be desired to pass the change down through recursive makes. That will not happen automatically because the original command-line override is passed through MAKEFLAGS as a command-line override to the sub-make, ignoring the local "override" declaration. Explicitly exporting the variable doesn't help, because command-line overrides override exported variables.

Two simple solutions seem reasonable:

    override CFLAGS += -g


    override CFLAGS += -g

Unfortunately, the first one never works, and the second one only works if CFLAGS is actually overridden on the command line.



ifeq "$(MAKELEVEL)" "0"
override foo+=added
MAKEOVERRIDES += foo+=added
        @echo outer: 'foo is "$(foo)" from $(origin foo)'
        @echo inner: 'foo is "$(foo)" from $(origin foo)'


$ # This works fine
$ make -s foo=override
outer: foo is "override added" from override
inner: foo is "override added" from command line
$ # But without the command line override, it fails
$ make -s
outer: foo is "added" from override
inner: foo is "" from undefined


If we append to MAKEFLAGS, then the outcome is even worse:

$ cat Makefile
ifeq "$(MAKELEVEL)" "0"
override foo+=added
MAKEFLAGS += foo+=added
        @echo outer: 'foo is "$(foo)" from $(origin foo)'
        @echo inner: 'foo is "$(foo)" from $(origin foo)'

$ make -s foo=override
outer: foo is "override added" from override
inner: foo is "override" from command line

$ make -s
outer: foo is "added" from override
inner: foo is "" from undefined


Curiously, if we append to both MAKEFLAGS and MAKEOVERRIDES, the result is as desired.

The issue comes from the regeneration of MAKEFLAGS in define_makeflags. In particular, towards the end of that function, in the conditional starting at main.c:3237, MAKEFLAGS has "-- $(MAKEOVERRIDES)" added to it, but only if there were any command-line overrides. If there are no command-line overrides, then the exported value of MAKEFLAGS will consist only of flags, and the modification of MAKEOVERRIDES will be lost. Consequently, appending to MAKEOVERRIDES only works if there are command-line overrides.

If we append a definition to MAKEFLAGS, then MAKEFLAGS will be regenerated as `<flags> -- $(MAKEOVERRIDES)`, since the definition in MAKEFLAGS is considered a command-line override during the first scan of MAKEFLAGS. The actual command-line override read during the first scan is not retained in MAKEFLAGS, on the assumption that it will appear in MAKEOVERRIDES.

Unfortunately, MAKEOVERRIDES will not be set correctly in that case, because the stanza starting at main.c:1623 where MAKEOVERRIDES is created happens before the first scan of MAKEFLAGS, and thus does not include any variable settings which had been added to MAKEFLAGS. If there are command-line overrides from the command-line, MAKEOVERRIDES is set to ${-*-command-variables-*-} and -*-command-variables-*- is set to the list of command-line overrides, but in any event the modifications made to MAKEFLAGS will be lost.

If the modification is made to both MAKEFLAGS and MAKEOVERRIDES, then the modification will be passed to submakes, because the addition to MAKEFLAGS will cause MAKEFLAGS to include a reference to MAKEOVERRIDES, and the addition to MAKEOVERRIDES will therefore be used. (In fact, any setting in MAKEFLAGS would work.)

The simple resolution would be to unconditionally regenerate MAKEFLAGS with "-- $(MAKEOVERRIDES)", even if there are no command-line overrides, by changing line 3237 of main.c from:

    if (all && command_variables)


    if (all)

Rici Lake <rici>


(Note: upload size limit is set to 16384 kB, after insertion of the required escape characters.)

Attach Files:

No files currently attached


Depends on the following items: None found

Items that depend on this one: None found


Carbon-Copy List
  • -email is unavailable- added by psmith (Posted a comment)
  • -email is unavailable- added by rici (Submitted the item)

    Do you think this task is very important?
    If so, you can add your encouragement to it.
    This task has 0 encouragements so far.

    Only logged-in users can vote.




    Follow 3 latest changes.

    Date Changed by Updated Field Previous Value => Replaced by
    2019-05-19 psmith StatusNone => Fixed
        Open/ClosedOpen => Closed
        Fixed ReleaseNone => SCM

    Back to the top

    Powered by Savane 3.5