On Sat, Dec 26, 2020 at 05:19:55PM +0100, Klemens Nanni wrote:
> Our make(1) is behind NetBSD's and FreeBSD's make(1) on at least the
> rules of variable substitution.
> 
> Our DESCRIPION says
> 
>      There are seven different types of lines in a makefile: dependency lines,
>      shell commands, variable assignments, include statements, conditional
>      directives, for loops, and comments.  Of these, include statements,
>      conditional directives and for loops are extensions.
> 
> but our VARIABLES merely explains
> 
>      Variable substitution occurs at two distinct times, depending on where
>      the variable is being used.  Variables in dependency lines are expanded
>      as the line is read.  Variables in shell commands are expanded when the
>      shell command is executed.
> 
> and therefore fails to explain behaviour for the other five line types.
> 
> 
> http://man.netbsd.org/make.1#VARIABLE%20ASSIGNMENTS (same as FreeBSD in
> this regard) does go into more detail here:
> 
>     Variable substitution occurs at three distinct times, depending on where
>          the variable is being used.
>     
>          1.   Variables in dependency lines are expanded as the line is read.
>     
>          2.   Variables in shell commands are expanded when the shell command 
> is
>               executed.
>     
>          3.   ``.for'' loop index variables are expanded on each loop 
> iteration.
>               Note that other variables are not expanded inside loops so the 
> fol-
>               lowing example code:
>     
>               [...]
> 
> 
> Diff below sync this list in VARIABLES as is.
> 
> After that I'd like to expand it and explain behaviour for other types;
> I've scratched my head on make's behaviour for too long and the manual
> failed to cover this completely.
> 
> Feedback? OK?

I came across this again, so I would really like to fix our manual.

In https://marc.info/?l=openbsd-tech&m=160935207004852&w=2
on 2020-12-30 espie said:
> I do think we want to write something specific for .for loop variables
> which are actually very special compared to the rest.
> 
> I'm not incredibly happy with the way netbsd explains it, not surprisingly.

which didn't result in any update to our manual.

I'm still in favour of syncing with NetBSD (first), they're wording and
example explains the missing pieces.

We can gladly polish things afterwards if someone comes up with
something better.

OK?

Index: make.1
===================================================================
RCS file: /cvs/src/usr.bin/make/make.1,v
retrieving revision 1.134
diff -u -p -r1.134 make.1
--- make.1      11 Nov 2021 20:42:54 -0000      1.134
+++ make.1      13 Nov 2021 09:58:34 -0000
@@ -600,11 +600,48 @@ If the variable name contains only a sin
 braces or parentheses are not required.
 This shorter form is not recommended.
 .Pp
-Variable substitution occurs at two distinct times, depending on where
+Variable substitution occurs at three distinct times, depending on where
 the variable is being used.
+.Bl -enum
+.It
 Variables in dependency lines are expanded as the line is read.
+.It
 Variables in shell commands are expanded when the shell command is
 executed.
+.It
+.Dq .for
+loop index variables are expanded on each loop iteration.
+Note that other variables are not expanded inside loops so
+the following example code:
+.Bd -literal -offset indent
+
+.Dv .for i in 1 2 3
+a+=     ${i}
+j=      ${i}
+b+=     ${j}
+.Dv .endfor
+
+all:
+       @echo ${a}
+       @echo ${b}
+
+.Ed
+will print:
+.Bd -literal -offset indent
+1 2 3
+3 3 3
+
+.Ed
+Because while ${a} contains
+.Dq 1 2 3
+after the loop is executed, ${b}
+contains
+.Dq ${j} ${j} ${j}
+which expands to
+.Dq 3 3 3
+since after the loop completes ${j} contains
+.Dq 3 .
+.El
 .Pp
 The four different classes of variables (in order of increasing precedence)
 are:

Reply via email to