help-make
[Top][All Lists]
Advanced

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

Re: The -e option confuses the $(origin ) ?


From: Kaz Kylheku (gmake)
Subject: Re: The -e option confuses the $(origin ) ?
Date: Mon, 13 Sep 2021 07:16:29 -0700
User-agent: Roundcube Webmail/0.9.2

On 2021-09-13 06:16, Masahiro Yamada wrote:
On Mon, Sep 13, 2021 at 9:23 PM Kaz Kylheku (gmake)
<729-670-0061@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-*-}.

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-*-}.

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.





reply via email to

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