[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: export vs $(origin )
Re: export vs $(origin )
Fri, 03 Jul 2020 12:46:33 -0400
On Fri, 2020-07-03 at 11:50 +0200, Jan Beulich wrote:
> > For example if you change the above makefile:
> > export FOO
> > $(info FOO: $(origin FOO))
> > all: ; @env | grep FOO
> > then you run:
> > $ unset FOO; make
> > FOO: file
> > FOO=
> > make: 'all' is up to date.
> > you can see that "FOO" is in the environment in the recipe even
> > though it wasn't in the environment when make started.
> Well, okay, if this behavior is intentional, then may I ask that the
> documentation be adjusted to clarify this behavior (i.e. it is not
> just a convenience that the variables _can_ be assigned a value, but
> instead they always _will_ be assigned one, potentially empty)?
I think you are reading a lot more into the phrase "as a convenience"
than it was intended to convey. As the text/example after it makes
pretty clear (IMO), it's saying that instead of writing:
VAR = value
That "as a convenience" you could instead write:
export VAR = value
The convenience is just allowing this same behavior to be obtained in
one line instead of two lines. It's basically mimicking the same
behavior in the shell, where you can write either:
or, more conveniently:
If it's confusing then the change we could make is simply removing the
phrase "As a convenience", which would leave it saying:
You can define a variable and export it at the same time by doing:
We can also make clear, as a separate statement, that "export FOO" will
cause the variable FOO to be defined.
> Also, if this is intentional, then I suppose there is no solution to
> the problem I'm having except moving the export line(s) until after
> the variable(s) have been assigned to (or moving the $(origin )
> checks ahead of the export, which in my specific case is not really
Well, it's not really clear to me what the problem you're having is,
but if you want to ensure that variables that are not defined in the
makefile are not exported at all, but if they are defined in the
makefile they are exported, then you need to either always export them
when defining them but not elsewhere, or else if you have to put the
export line somewhere else other than the definition then you have test
the variable with $(origin ...) to make sure it's defined before
exporting it, because exporting it will force it to be defined as we've
> As an aside, I am still unconvinced the behavior you describe is the
> only one possibly sensible.
Sorry, I didn't mean to imply there was no other possible way this
could work. I agree there are other possibilities.
> I could as well view "export" as a directive to indicate to put the
> given variable(s) into the environment, but only if they've been
> assigned a (potentially empty) value. I.e. these two would then have
> different behavior:
> export XYZ
> export XYZ=
> Which means the current behavior could be achieved for people wanting
> it, while export wouldn't unconditionally have the effect of also
> defining the variable(s)
This would be backward-incompatible, and also it would add some
complexity: we'd have to add a new state to variable storage to allow a
variable to be known to make (to hold the flag that says it's
exportable) but to actually not be considered defined (until/unless it
was set), so it wouldn't be added to the child's environment. This
latter is not a huge amount of work, I'm just saying it's not free :).
I have to say I'm not convinced that the behavior you're suggesting is
better. Although obviously you have a need for it so the fact that
it's hard to accomplish today makes that change seem attractive, to me
it seems confusing and unexpected. I think people will expect that
they have "export XYZ" in their makefile, they will have the variable
XYZ in their environment. Even if they don't set it to a value. And
the subtlety of "export FOO" versus "export FOO=" seems a bit too much
"inside baseball" to me.
> (i.e. more along the lines of what current documentation says).
As above, I disagree that this is what the documentation says... I do
believe it describes exactly what the current behavior is. However
obviously this is not clear to everyone :) so we should address it.