varname-dot-makeflags.mk revision 1.2 1 1.2 rillig # $NetBSD: varname-dot-makeflags.mk,v 1.2 2023/02/25 06:54:08 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.2 rillig all: dollars_stage_0 #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.2 rillig # Demonstrate that '$' characters are altered when they are passed on to child
30 1.2 rillig # make processes via MAKEFLAGS.
31 1.2 rillig dollars_stage_0:
32 1.2 rillig @echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>'
33 1.2 rillig # The '$$$$' gets parsed as a literal '$$', making the actual variable
34 1.2 rillig # value '$${varname}'.
35 1.2 rillig #
36 1.2 rillig # When Main_ExportMAKEFLAGS adds the variable DOLLARS to MAKEFLAGS, it
37 1.2 rillig # first evaluates the variable value, resulting in '${varname}'.
38 1.2 rillig #
39 1.2 rillig # This value is then escaped as '\$\{varname\}', to ensure that the
40 1.2 rillig # variable is later interpreted as a single shell word.
41 1.2 rillig @${MAKE} -f ${MAKEFILE} dollars_stage_1 DOLLARS='$$$${varname}'
42 1.2 rillig
43 1.2 rillig # The environment variable 'MAKEFLAGS' now contains the variable assignment
44 1.2 rillig # 'DOLLARS=\$\{varname\}', including the backslashes.
45 1.2 rillig #
46 1.2 rillig # expect: dollars_stage_1: env MAKEFLAGS=< -r -k DOLLARS=\$\{varname\}>
47 1.2 rillig #
48 1.2 rillig # When Main_ParseArgLine calls Str_Words to parse the flags from MAKEFLAGS, it
49 1.2 rillig # removes the backslashes, resulting in the plain variable assignment
50 1.2 rillig # 'DOLLARS=${varname}'.
51 1.2 rillig dollars_stage_1:
52 1.2 rillig @echo "$@: env MAKEFLAGS=<$$MAKEFLAGS>"
53 1.2 rillig
54 1.2 rillig # At this point, evaluating the environment variable 'MAKEFLAGS' has
55 1.2 rillig # strange side effects, as the string '\$\{varname\}' is interpreted
56 1.2 rillig # as:
57 1.2 rillig #
58 1.2 rillig # \ a single backslash
59 1.2 rillig # $\ the value of the variable named '\'
60 1.2 rillig # {varname\} a literal string
61 1.2 rillig #
62 1.2 rillig # Since the variable name '\' is not defined, the resulting value is
63 1.2 rillig # '\{varname\}'.
64 1.2 rillig @echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>'
65 1.2 rillig
66 1.2 rillig # The modifier ':q' escapes a '$' in the variable value to '$$', but
67 1.2 rillig # it's too late, as that modifier applies after the expression has
68 1.2 rillig # been evaluated.
69 1.2 rillig @echo '$@: MAKEFLAGS:q=<'${MAKEFLAGS:q}'>'
70 1.2 rillig
71 1.2 rillig # The value of the variable DOLLARS is now '${varname}'. Since there
72 1.2 rillig # is no variable named 'varname', this expression evaluates to ''.
73 1.2 rillig @${MAKE} -f ${MAKEFILE} dollars_stage_2
74 1.2 rillig
75 1.2 rillig # Uncomment these lines to see the above variable expansions in action.
76 1.2 rillig #${:U\\}=backslash
77 1.2 rillig #varname=varvalue
78 1.2 rillig
79 1.2 rillig dollars_stage_2:
80 1.2 rillig @echo "$@: env MAKEFLAGS=<$$MAKEFLAGS>"
81 1.2 rillig @echo '$@: dollars=<'${DOLLARS:Q}'>'
82 1.2 rillig @echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>'
83 1.2 rillig @${MAKE} -f ${MAKEFILE} dollars_stage_3
84 1.2 rillig
85 1.2 rillig dollars_stage_3:
86 1.2 rillig @echo "$@: env MAKEFLAGS=<$$MAKEFLAGS>"
87 1.2 rillig @echo '$@: dollars=<'${DOLLARS:Uundefined:Q}'>'
88 1.2 rillig @echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>'
89 1.2 rillig
90 1.2 rillig
91 1.2 rillig # Demonstrates in which exact order the MAKEFLAGS are built together from the
92 1.2 rillig # parent MAKEFLAGS and the flags from the command line, in particular that
93 1.2 rillig # variable assignments are passed at the end, after the options.
94 1.2 rillig append_stage_0:
95 1.2 rillig @echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>'
96 1.2 rillig @${MAKE} -Dbefore-0 -f ${MAKEFILE} append_stage_1 VAR0=value -Dafter-0
97 1.2 rillig
98 1.2 rillig append_stage_1:
99 1.2 rillig @echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>'
100 1.2 rillig @${MAKE} -Dbefore-1 -f ${MAKEFILE} append_stage_2 VAR1=value -Dafter-1
101 1.2 rillig
102 1.2 rillig append_stage_2:
103 1.2 rillig @echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>'
104 1.2 rillig @${MAKE} -Dbefore-2 -f ${MAKEFILE} append_stage_3 VAR2=value -Dafter-2
105 1.2 rillig
106 1.2 rillig append_stage_3:
107 1.2 rillig @echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>'
108