On Mon, Sep 13, 2021 at 11:16 PM Kaz Kylheku (gmake) <729-670-0...@kylheku.com> wrote: > > On 2021-09-13 06:16, Masahiro Yamada wrote: > > On Mon, Sep 13, 2021 at 9:23 PM Kaz Kylheku (gmake) > > <729-670-0...@kylheku.com> wrote: > >> > >> On 2021-09-13 00:28, Masahiro Yamada wrote: > >> > masahiro@oscar:~/workspace/foo$ export FOO=2 > >> > masahiro@oscar:~/workspace/foo$ make > >> > Makefile:1: the origin of FOO is: environment > >> > Makefile:2: the value of FOO is: 2 > >> > make -e -f Makefile.sub1 FOO=1 > >> > >> Note that this FOO=1 will be exported to the environment. See the > >> GNU Make 4.3 manual, section 5.7.2 Communicating Variables to a > >> Sub-make: > >> > >> "Except by explicit request, make exports a variable only if it is > >> either defined in the environment initially or set on the command > >> line, and if its name consists only of letters, numbers, and > >> underscores." > > > > > > This is not answering my question. > > OK. > > > Without -e, all the sub-makes remember that > > FOO's origin is 'command line'. > > OK, that is the real issue. > > Now, of course, the sub-make is not literally getting > FOO=1 on the command line. Command-line variables are passed > to sub-makes via the MAKEFLAGS environment variable. > > The -e option makes a difference here. > > $ cat Makefile > $(info FOO (from $(origin FOO)) is $(FOO)) > > .PHONY: all > > all: > env | grep '^MAKE' > > > First, baseline: no arguments, no environment. This is make 4.1: > > > $ make > FOO (from undefined) is > env | grep '^MAKE' > MAKEFLAGS= > MAKE_TERMERR=/dev/pts/1 > MAKELEVEL=1 > MAKE_TERMOUT=/dev/pts/1 > > $ make -e > FOO (from undefined) is > env | grep '^MAKE' > MAKEFLAGS=e > MAKE_TERMERR=/dev/pts/1 > MAKELEVEL=1 > MAKE_TERMOUT=/dev/pts/1 > > Now, with a variable assignment: > > $ make FOO=1 > FOO (from command line) is 1 > env | grep '^MAKE' > MAKEFLAGS= -- FOO=1 > MAKE_TERMERR=/dev/pts/1 > MAKELEVEL=1 > MAKEOVERRIDES=${-*-command-variables-*-} > MAKE_TERMOUT=/dev/pts/1 > > $ make -e FOO=1 > FOO (from command line) is 1 > env | grep '^MAKE' > MAKEFLAGS=e -- $(MAKEOVERRIDES) > MAKE_TERMERR=/dev/pts/1 > MAKELEVEL=1 > MAKEOVERRIDES=${-*-command-variables-*-} > MAKE_TERMOUT=/dev/pts/1 > > Without -e, MAKEFLAGS carries the command line variables > itself. > > Without -e, MAKEFLAGS contains a reference to ${MAKEOVERRIDES}, > which contains a reference to ${-*-command-variables-*-}.
With -e, MAKEFLAGS contains... ^^^^ > But this -*-command-variables-*- is purely internal; it is > not in the environment. It looks like it will refer to the > literal command line. And so that could be why in the > grandchild make, you are not seeing the origin of FOO as > command line; it doesn't appear in ${-*-command-variables-*-}. I do not have much knowledge of GNU make internal, but your insight sounds right. We have not got any feedback from Paul, but this seems like a bug. Even if it is a low-priority, let me raise this in the bug tracking system. > It seems odd because -e is supposed to be about the precedence > between variables defined in the Makefile, versus environment. > Yet this shows it is interacting with command line variable > semantics. > > In the manual, -e/--environment-overrides is not specified > in great detail. The Options Summary just says: > > Give variables taken from the environment precedence over > variables from makefiles. > > and then refers to: > > See Variables from the Environment. > > That section only mentions -e in a parenthetical statement, > and warns that using it is not recommended practice: > > (If the ā-eā flag is specified, then values from the environment > override assignments in the makefile. See Summary of Options. > But this is not recommended practice.) > > I.e. it says nothing more or less than the Summary of Options, > except for adding that -e isn't recommended. > > It looks like -e is some sort of experimental hack with mysterious > effects that is under-documented on purpose, with a warning not to > use it. > > -- Best Regards Masahiro Yamada