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 Sep 21 02:59:44 2015  
 
Severity: 3 - NormalItem Group: Bug
Status: NonePrivacy: Public
Assigned to: NoneOpen/Closed: Open
Component Version: 4.1Operating System: POSIX-Based
Fixed Release: NoneTriage Status: None

Add a New Comment (Rich MarkupRich Markup):
   

You are not logged in

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

 

Wed Sep 30 19:28:24 2015, 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 Sep 28 16:59:35 2015, comment #1:

Simplified example:

#!/bin/bash
#\
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.

Anonymous
Mon Sep 21 02:59:44 2015, 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
MAKEFLAGS += CFLAGS+=-g

or

override CFLAGS += -g
MAKEOVERRIDES += CFLAGS+=-g

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

---

Makefile:

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

---

$ # 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
all:
@echo outer: 'foo is "$(foo)" from $(origin foo)'
@$(MAKE)
else
all:
@echo inner: 'foo is "$(foo)" from $(origin foo)'
endif

$ 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)

to

if (all)

Rici Lake <rici>

 

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

Attach File(s):
   
   
Comment:
   

No files currently attached

 

Depends on the following items: None found

Items that depend on this one: None found

 

Carbon-Copy List
  • -unavailable- added by rici (Submitted the item)
  •  

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

    Only logged-in users can vote.

     

    Please enter the title of George Orwell's famous dystopian book (it's a date):

     

     

    No Changes Have Been Made to This Item

    Back to the top


    Powered by Savane 3.1-cleanup1