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