varname-dot-makeflags.mk revision 1.2 1 # $NetBSD: varname-dot-makeflags.mk,v 1.2 2023/02/25 06:54:08 rillig Exp $
2 #
3 # Tests for the special .MAKEFLAGS variable, which collects almost all
4 # command line arguments and passes them on to any child processes via
5 # the environment variable MAKEFLAGS (without leading '.').
6 #
7 # See also:
8 # varname-dot-makeoverrides.mk
9
10 all: dollars_stage_0 #spaces_stage_0 dollars_stage_0 append_stage_0
11
12
13 # When options are parsed, the option and its argument are appended as
14 # separate words to .MAKEFLAGS. Special characters in the option argument
15 # are not quoted though. It seems to have not been necessary since at least
16 # 1993.
17 spaces_stage_0:
18 @echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>'
19 @echo "$@: env MAKEFLAGS=<$$MAKEFLAGS>"
20 @${MAKE} -f ${MAKEFILE} spaces_stage_1 -d00000 -D"VARNAME WITH SPACES"
21
22 # At this point, the 'VARNAME WITH SPACES' is no longer recognizable as a
23 # single command line argument. In practice, variable names don't contain
24 # spaces.
25 spaces_stage_1:
26 @echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>'
27 @echo "$@: env MAKEFLAGS=<$$MAKEFLAGS>"
28
29 # Demonstrate that '$' characters are altered when they are passed on to child
30 # make processes via MAKEFLAGS.
31 dollars_stage_0:
32 @echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>'
33 # The '$$$$' gets parsed as a literal '$$', making the actual variable
34 # value '$${varname}'.
35 #
36 # When Main_ExportMAKEFLAGS adds the variable DOLLARS to MAKEFLAGS, it
37 # first evaluates the variable value, resulting in '${varname}'.
38 #
39 # This value is then escaped as '\$\{varname\}', to ensure that the
40 # variable is later interpreted as a single shell word.
41 @${MAKE} -f ${MAKEFILE} dollars_stage_1 DOLLARS='$$$${varname}'
42
43 # The environment variable 'MAKEFLAGS' now contains the variable assignment
44 # 'DOLLARS=\$\{varname\}', including the backslashes.
45 #
46 # expect: dollars_stage_1: env MAKEFLAGS=< -r -k DOLLARS=\$\{varname\}>
47 #
48 # When Main_ParseArgLine calls Str_Words to parse the flags from MAKEFLAGS, it
49 # removes the backslashes, resulting in the plain variable assignment
50 # 'DOLLARS=${varname}'.
51 dollars_stage_1:
52 @echo "$@: env MAKEFLAGS=<$$MAKEFLAGS>"
53
54 # At this point, evaluating the environment variable 'MAKEFLAGS' has
55 # strange side effects, as the string '\$\{varname\}' is interpreted
56 # as:
57 #
58 # \ a single backslash
59 # $\ the value of the variable named '\'
60 # {varname\} a literal string
61 #
62 # Since the variable name '\' is not defined, the resulting value is
63 # '\{varname\}'.
64 @echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>'
65
66 # The modifier ':q' escapes a '$' in the variable value to '$$', but
67 # it's too late, as that modifier applies after the expression has
68 # been evaluated.
69 @echo '$@: MAKEFLAGS:q=<'${MAKEFLAGS:q}'>'
70
71 # The value of the variable DOLLARS is now '${varname}'. Since there
72 # is no variable named 'varname', this expression evaluates to ''.
73 @${MAKE} -f ${MAKEFILE} dollars_stage_2
74
75 # Uncomment these lines to see the above variable expansions in action.
76 #${:U\\}=backslash
77 #varname=varvalue
78
79 dollars_stage_2:
80 @echo "$@: env MAKEFLAGS=<$$MAKEFLAGS>"
81 @echo '$@: dollars=<'${DOLLARS:Q}'>'
82 @echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>'
83 @${MAKE} -f ${MAKEFILE} dollars_stage_3
84
85 dollars_stage_3:
86 @echo "$@: env MAKEFLAGS=<$$MAKEFLAGS>"
87 @echo '$@: dollars=<'${DOLLARS:Uundefined:Q}'>'
88 @echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>'
89
90
91 # Demonstrates in which exact order the MAKEFLAGS are built together from the
92 # parent MAKEFLAGS and the flags from the command line, in particular that
93 # variable assignments are passed at the end, after the options.
94 append_stage_0:
95 @echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>'
96 @${MAKE} -Dbefore-0 -f ${MAKEFILE} append_stage_1 VAR0=value -Dafter-0
97
98 append_stage_1:
99 @echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>'
100 @${MAKE} -Dbefore-1 -f ${MAKEFILE} append_stage_2 VAR1=value -Dafter-1
101
102 append_stage_2:
103 @echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>'
104 @${MAKE} -Dbefore-2 -f ${MAKEFILE} append_stage_3 VAR2=value -Dafter-2
105
106 append_stage_3:
107 @echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>'
108