Home | History | Annotate | Line # | Download | only in unit-tests
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