bug-make
[Top][All Lists]
Advanced

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

Re: New conditional assignment facility


From: Paul Smith
Subject: Re: New conditional assignment facility
Date: Sun, 21 Jan 2024 11:17:40 -0500
User-agent: Evolution 3.50.2 (by Flathub.org)

On Sat, 2024-01-20 at 22:18 -0500, Dmitry Goncharov wrote:
> > Either we could follow the example of "+=" and say that the assignment
> > type in "+:=" only takes effect if the variable doesn't already have a
> > type but if it does that type is preserved, so in the above example FOO
> > would continue to be recursively expanded in spite of "+:=", so FOO has
> > a value of "$(bar) $(biz)" and $(FOO) gives "1 2".
> > 
> > Or we could say that "+=" is a special case where we follow the type of
> > the existing variable, but for the other operators we first expand the
> > right hand side then append the result regardless of the original type.
> > So in the above example FOO is still a recursive variable, BUT $(baz)
> > is expanded immediately before appending so the value of FOO would be
> > "$(bar) yy" and $(FOO) gives "1 yy".
> > 
> > Neither of these is great, in that they both will cause people to be
> > surprised, in different situations.
> 
> i like option one. It is simple to explain in the manual and, as far
> as i can tell, option one does what users want.
> As long as the manual says something like "when there is no variable
> +:= creates a simple variable, otherwise +:= behaves the same as :="
> is there still room for surprises?

I think you wrote that wrong: I think you mean "otherwise +:= behaves
the same as +="... ?

I think the behavior here would be very surprising in a number of
situations as I'll try to show below.

> i suspect option two is a lot trickier to use in a makefile. Option
> two introduces a doubt in the mind of a makefile author. If the
> makefile author knows that all the appends +=, :+=, ::+=+, :::+=

Just for clarity, it's "+=", "+:=", "+::=", "+:::=", and "+!="; the
plus is the first character in the token, not right before the "=".

> follow the variable flavor, once the variable is created, then the
> author sees that a variable is recursive at the top of a makefile and
> knows anything can be appended to the variable at the bottom of the
> makefile and the value will contain that anything at build time. If
> we go with option two then the author does not have this knowledge.
> In your example, one scenario is that the author misses that the
> assignment is +:= and sets biz to 2 and expects that FOO contains "1
> 2" at build time. Another scenario is that 'FOO +:= $(biz)' is
> introduced long after 'biz = 2'. Similarly, if the author wants to
> introduce a +:= assignment somewhere in a makefile, they have to
> check that the makefile does not contain another assignment later. In
> our example, if the author wanted to introduce FOO +:= $(biz) they
> will have to check that biz is not assigned later.

I don't think I agree with you here.

Let's take one obviously bad case: the != operator.  I don't see any
legitimate way that this can be used if we choose option one.  Suppose
we have:

    $(X)foo != echo hello

    foo +:= $(BAR)

Now what do we do?  We clearly can't say that the RHS of the append
assignment should be treated as a shell script!  It can't work to say
that the value to be appended _might_ be appended using simple
expansion if X has a value, _or else_ be run as a shell script and
append the result if X is empty.

And similarly for the other way around: it won't work if the value was
originally assigned with ":=" and then you use "+!=" and instead of
expanding the shell command it simply expands and appends the value.


The idea behind option two is that you don't need to know what other
settings of the variable had previously been created.  The only thing
you care about is how you want to handle THIS assignment; that is, you
expand (or not) the RHS of THIS assignment according to the operator,
then append that value.

So for example if you see "+!=" you know that the RHS of this
assignment will definitely be expanded as a shell script, then the
results will be appended to the variable.


The question is what happens in this scenario:

  foo = $(bar)

  foo +:= $(baz)

What we would like to see is that the RHS of the "+:=" is expanded
immediately (if the user didn't want it to be expanded immediately then
they'd obviously not use "+:=") then appended.  But this is kind of
gross because we're appending an already-expanded value to a recursive
variable, which means that already-expanded value will be expanded
AGAIN when the variable is expanded which is not what you want.

Similarly, what if we have:

  foo := $(bar)

  foo +:::= $(baz)

Here the foo variable is marked simple, but we are appending an escaped
value to it which won't be expanded later.

Maybe we need to consider escaping/expanding values properly for the
variable they are to be assigned to, after we expand them based on the
current operator.

I will try to write down what I'm thinking in a separate email, maybe
as a table.  The need for such a table of course is depressing because
it means we can't just have a simple rule.  But I just don't think that
a simple rule can work given all the competing requirements.

I guess the only "truly correct" behavior would be to keep the actual
value of the variable as a list of separate chunks of text each with
its own type when append is used, and resolve each chunk according to
its particular operator.  But I definitely don't want to do that so
maybe we can do something mostly equivalent.

To be honest things would be simpler if the current behavior of the :=
operator didn't exist at all, and GNU Make had implemented it as the
behavior of the ":::=" operator instead.  Then all variables would be
"recursive" and we'd handle internal "$" by escaping them.

It would make variable expansion slower than the current ":=" but I
doubt it would be noticeable.

If only Joerg were still with us, he'd be so happy to read that :)

-- 
Paul D. Smith <psmith@gnu.org>            Find some GNU make tips at:
https://www.gnu.org                       http://make.mad-scientist.net
"Please remain calm...I may be mad, but I am a professional." --Mad
Scientist



reply via email to

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