Module Name: src Committed By: rillig Date: Sat Feb 25 06:54:08 UTC 2023
Modified Files: src/usr.bin/make/unit-tests: varname-dot-makeflags.exp varname-dot-makeflags.mk varname-dot-makeoverrides.exp varname-dot-makeoverrides.mk Log Message: tests/make: reproduce and explain '$' in MAKEFLAGS https://mail-index.netbsd.org/current-users/2023/02/24/msg043633.html To generate a diff of this commit: cvs rdiff -u -r1.1 -r1.2 \ src/usr.bin/make/unit-tests/varname-dot-makeflags.exp \ src/usr.bin/make/unit-tests/varname-dot-makeflags.mk cvs rdiff -u -r1.2 -r1.3 \ src/usr.bin/make/unit-tests/varname-dot-makeoverrides.exp cvs rdiff -u -r1.4 -r1.5 \ src/usr.bin/make/unit-tests/varname-dot-makeoverrides.mk Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.bin/make/unit-tests/varname-dot-makeflags.exp diff -u src/usr.bin/make/unit-tests/varname-dot-makeflags.exp:1.1 src/usr.bin/make/unit-tests/varname-dot-makeflags.exp:1.2 --- src/usr.bin/make/unit-tests/varname-dot-makeflags.exp:1.1 Tue Dec 1 20:37:30 2020 +++ src/usr.bin/make/unit-tests/varname-dot-makeflags.exp Sat Feb 25 06:54:08 2023 @@ -1,3 +1,11 @@ -echo "$MAKEFLAGS" - -r -k -d 00000 -D VARNAME WITH SPACES +dollars_stage_0: MAKEFLAGS=< -r -k > +dollars_stage_1: env MAKEFLAGS=< -r -k DOLLARS=\$\{varname\}> +dollars_stage_1: MAKEFLAGS=< -r -k DOLLARS=\{varname\}> +dollars_stage_1: MAKEFLAGS:q=< -r -k DOLLARS=\{varname\}> +dollars_stage_2: env MAKEFLAGS=< -r -k DOLLARS=> +dollars_stage_2: dollars=<> +dollars_stage_2: MAKEFLAGS=< -r -k DOLLARS=> +dollars_stage_3: env MAKEFLAGS=< -r -k DOLLARS=> +dollars_stage_3: dollars=<> +dollars_stage_3: MAKEFLAGS=< -r -k DOLLARS=> exit status 0 Index: src/usr.bin/make/unit-tests/varname-dot-makeflags.mk diff -u src/usr.bin/make/unit-tests/varname-dot-makeflags.mk:1.1 src/usr.bin/make/unit-tests/varname-dot-makeflags.mk:1.2 --- src/usr.bin/make/unit-tests/varname-dot-makeflags.mk:1.1 Tue Dec 1 20:37:30 2020 +++ src/usr.bin/make/unit-tests/varname-dot-makeflags.mk Sat Feb 25 06:54:08 2023 @@ -1,15 +1,107 @@ -# $NetBSD: varname-dot-makeflags.mk,v 1.1 2020/12/01 20:37:30 rillig Exp $ +# $NetBSD: varname-dot-makeflags.mk,v 1.2 2023/02/25 06:54:08 rillig Exp $ # # Tests for the special .MAKEFLAGS variable, which collects almost all # command line arguments and passes them on to any child processes via # the environment variable MAKEFLAGS (without leading '.'). +# +# See also: +# varname-dot-makeoverrides.mk + +all: dollars_stage_0 #spaces_stage_0 dollars_stage_0 append_stage_0 + # When options are parsed, the option and its argument are appended as # separate words to .MAKEFLAGS. Special characters in the option argument -# are not quoted though. It seems to have not been necessary at least from -# 1993 until 2020. -.MAKEFLAGS: -d00000 -D"VARNAME WITH SPACES" - -all: - echo "$$MAKEFLAGS" - @:; +# are not quoted though. It seems to have not been necessary since at least +# 1993. +spaces_stage_0: + @echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>' + @echo "$@: env MAKEFLAGS=<$$MAKEFLAGS>" + @${MAKE} -f ${MAKEFILE} spaces_stage_1 -d00000 -D"VARNAME WITH SPACES" + +# At this point, the 'VARNAME WITH SPACES' is no longer recognizable as a +# single command line argument. In practice, variable names don't contain +# spaces. +spaces_stage_1: + @echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>' + @echo "$@: env MAKEFLAGS=<$$MAKEFLAGS>" + +# Demonstrate that '$' characters are altered when they are passed on to child +# make processes via MAKEFLAGS. +dollars_stage_0: + @echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>' + # The '$$$$' gets parsed as a literal '$$', making the actual variable + # value '$${varname}'. + # + # When Main_ExportMAKEFLAGS adds the variable DOLLARS to MAKEFLAGS, it + # first evaluates the variable value, resulting in '${varname}'. + # + # This value is then escaped as '\$\{varname\}', to ensure that the + # variable is later interpreted as a single shell word. + @${MAKE} -f ${MAKEFILE} dollars_stage_1 DOLLARS='$$$${varname}' + +# The environment variable 'MAKEFLAGS' now contains the variable assignment +# 'DOLLARS=\$\{varname\}', including the backslashes. +# +# expect: dollars_stage_1: env MAKEFLAGS=< -r -k DOLLARS=\$\{varname\}> +# +# When Main_ParseArgLine calls Str_Words to parse the flags from MAKEFLAGS, it +# removes the backslashes, resulting in the plain variable assignment +# 'DOLLARS=${varname}'. +dollars_stage_1: + @echo "$@: env MAKEFLAGS=<$$MAKEFLAGS>" + + # At this point, evaluating the environment variable 'MAKEFLAGS' has + # strange side effects, as the string '\$\{varname\}' is interpreted + # as: + # + # \ a single backslash + # $\ the value of the variable named '\' + # {varname\} a literal string + # + # Since the variable name '\' is not defined, the resulting value is + # '\{varname\}'. + @echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>' + + # The modifier ':q' escapes a '$' in the variable value to '$$', but + # it's too late, as that modifier applies after the expression has + # been evaluated. + @echo '$@: MAKEFLAGS:q=<'${MAKEFLAGS:q}'>' + + # The value of the variable DOLLARS is now '${varname}'. Since there + # is no variable named 'varname', this expression evaluates to ''. + @${MAKE} -f ${MAKEFILE} dollars_stage_2 + +# Uncomment these lines to see the above variable expansions in action. +#${:U\\}=backslash +#varname=varvalue + +dollars_stage_2: + @echo "$@: env MAKEFLAGS=<$$MAKEFLAGS>" + @echo '$@: dollars=<'${DOLLARS:Q}'>' + @echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>' + @${MAKE} -f ${MAKEFILE} dollars_stage_3 + +dollars_stage_3: + @echo "$@: env MAKEFLAGS=<$$MAKEFLAGS>" + @echo '$@: dollars=<'${DOLLARS:Uundefined:Q}'>' + @echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>' + + +# Demonstrates in which exact order the MAKEFLAGS are built together from the +# parent MAKEFLAGS and the flags from the command line, in particular that +# variable assignments are passed at the end, after the options. +append_stage_0: + @echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>' + @${MAKE} -Dbefore-0 -f ${MAKEFILE} append_stage_1 VAR0=value -Dafter-0 + +append_stage_1: + @echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>' + @${MAKE} -Dbefore-1 -f ${MAKEFILE} append_stage_2 VAR1=value -Dafter-1 + +append_stage_2: + @echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>' + @${MAKE} -Dbefore-2 -f ${MAKEFILE} append_stage_3 VAR2=value -Dafter-2 + +append_stage_3: + @echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>' Index: src/usr.bin/make/unit-tests/varname-dot-makeoverrides.exp diff -u src/usr.bin/make/unit-tests/varname-dot-makeoverrides.exp:1.2 src/usr.bin/make/unit-tests/varname-dot-makeoverrides.exp:1.3 --- src/usr.bin/make/unit-tests/varname-dot-makeoverrides.exp:1.2 Sat Feb 25 00:09:52 2023 +++ src/usr.bin/make/unit-tests/varname-dot-makeoverrides.exp Sat Feb 25 06:54:08 2023 @@ -1,5 +1,8 @@ -make -r -f varname-dot-makeoverrides.mk dollars_stage_2 DOLLARS='$${varname}' -stage 2: dollars=<${varname}> -make -r -f varname-dot-makeoverrides.mk dollars_stage_3 -stage 3: dollars=<> +all: overrides=<> +make -f varname-dot-makeoverrides.mk stage_1 VAR=value +stage_1: overrides=< VAR> +make -f varname-dot-makeoverrides.mk stage_2 +stage_2: overrides=< VAR> +make -f varname-dot-makeoverrides.mk stage_3 +stage_3: overrides=< VAR> exit status 0 Index: src/usr.bin/make/unit-tests/varname-dot-makeoverrides.mk diff -u src/usr.bin/make/unit-tests/varname-dot-makeoverrides.mk:1.4 src/usr.bin/make/unit-tests/varname-dot-makeoverrides.mk:1.5 --- src/usr.bin/make/unit-tests/varname-dot-makeoverrides.mk:1.4 Sat Feb 25 00:09:52 2023 +++ src/usr.bin/make/unit-tests/varname-dot-makeoverrides.mk Sat Feb 25 06:54:08 2023 @@ -1,18 +1,23 @@ -# $NetBSD: varname-dot-makeoverrides.mk,v 1.4 2023/02/25 00:09:52 rillig Exp $ +# $NetBSD: varname-dot-makeoverrides.mk,v 1.5 2023/02/25 06:54:08 rillig Exp $ # -# Tests for the special .MAKEOVERRIDES variable. +# Tests for the special .MAKEOVERRIDES variable, which lists the names of the +# variables that are passed on to child processes via the MAKEFLAGS +# environment variable. +# +# See also: +# varname-dot-makeflags.mk all: - @${MAKE} -r -f ${MAKEFILE} dollars_stage_1 + @echo '$@: overrides=<'${.MAKEOVERRIDES:Uundefined:Q}'>' + ${MAKE} -f ${MAKEFILE} stage_1 VAR=value -# Demonstrate that '$' characters are altered when they are passed on to child -# make processes via .MAKEOVERRIDES and MAKEFLAGS. -dollars_stage_1: - ${MAKE} -r -f ${MAKEFILE} dollars_stage_2 DOLLARS='$$$${varname}' +stage_1: + @echo '$@: overrides=<'${.MAKEOVERRIDES:Q}'>' + ${MAKE} -f ${MAKEFILE} stage_2 -dollars_stage_2: - @echo 'stage 2: dollars=<${DOLLARS}>' - ${MAKE} -r -f ${MAKEFILE} dollars_stage_3 +stage_2: + @echo '$@: overrides=<'${.MAKEOVERRIDES:Q}'>' + ${MAKE} -f ${MAKEFILE} stage_3 -dollars_stage_3: - @echo 'stage 3: dollars=<${DOLLARS}>' +stage_3: + @echo '$@: overrides=<'${.MAKEOVERRIDES:Q}'>'