Home | History | Annotate | Line # | Download | only in unit-tests
varname-dot-makeflags.mk revision 1.5
      1  1.5  rillig # $NetBSD: varname-dot-makeflags.mk,v 1.5 2023/02/25 11:11:16 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.5  rillig all: spaces_stage_0 dollars_stage_0 append_stage_0 override_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.4  rillig 
     35  1.4  rillig 	# The '$$$$' becomes a literal '$$' when building the '${MAKE}'
     36  1.4  rillig 	# command line, making the actual argument 'DOLLARS=$${varname}'.
     37  1.4  rillig 	# At this stage, MAKEFLAGS is not yet involved.
     38  1.2  rillig 	@${MAKE} -f ${MAKEFILE} dollars_stage_1 DOLLARS='$$$${varname}'
     39  1.2  rillig 
     40  1.4  rillig .if make(dollars_stage_1)
     41  1.4  rillig # At this point, the variable 'DOLLARS' contains '$${varname}', which
     42  1.4  rillig # evaluates to a literal '$' followed by '{varname}'.
     43  1.4  rillig .  if ${DOLLARS} != "\${varname}"
     44  1.4  rillig .    error
     45  1.4  rillig .  endif
     46  1.4  rillig .endif
     47  1.2  rillig dollars_stage_1:
     48  1.4  rillig 	# At this point, the stage 1 make provides the environment variable
     49  1.4  rillig 	# 'MAKEFLAGS' to its child processes, even if the child process is not
     50  1.4  rillig 	# another make.
     51  1.4  rillig 	#
     52  1.4  rillig 	# expect: dollars_stage_1: env MAKEFLAGS=< -r -k DOLLARS=\$\{varname\}>
     53  1.4  rillig 	#
     54  1.4  rillig 	# The 'DOLLARS=\$\{varname\}' assignment is escaped so that the stage
     55  1.4  rillig 	# 2 make will see it as a single word.
     56  1.2  rillig 	@echo "$@: env MAKEFLAGS=<$$MAKEFLAGS>"
     57  1.2  rillig 
     58  1.4  rillig 	# At this point, evaluating the environment variable 'MAKEFLAGS' leads
     59  1.4  rillig 	# to strange side effects as the string '\$\{varname\}' is interpreted
     60  1.2  rillig 	# as:
     61  1.2  rillig 	#
     62  1.4  rillig 	#	\		a literal string of a single backslash
     63  1.2  rillig 	#	$\		the value of the variable named '\'
     64  1.2  rillig 	#	{varname\}	a literal string
     65  1.2  rillig 	#
     66  1.2  rillig 	# Since the variable name '\' is not defined, the resulting value is
     67  1.4  rillig 	# '\{varname\}'.  Make doesn't handle isolated '$' characters in
     68  1.4  rillig 	# strings well, instead each '$' has to be part of a '$$' or be part
     69  1.4  rillig 	# of a subexpression like '${VAR}'.
     70  1.2  rillig 	@echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>'
     71  1.2  rillig 
     72  1.4  rillig 	# The modifier ':q' preserves a '$$' in an expression value instead of
     73  1.4  rillig 	# expanding it to a single '$', but it's already too late, as that
     74  1.4  rillig 	# modifier applies after the expression has been evaluated.  Except
     75  1.4  rillig 	# for debug logging, there is no way to process strings that contain
     76  1.4  rillig 	# isolated '$'.
     77  1.2  rillig 	@echo '$@: MAKEFLAGS:q=<'${MAKEFLAGS:q}'>'
     78  1.2  rillig 
     79  1.2  rillig 	@${MAKE} -f ${MAKEFILE} dollars_stage_2
     80  1.2  rillig 
     81  1.4  rillig .if make(dollars_stage_2)
     82  1.4  rillig # At this point, the variable 'DOLLARS' contains '${varname}', and since
     83  1.4  rillig # 'varname' is undefined, that expression evaluates to an empty string.
     84  1.4  rillig .  if ${DOLLARS} != ""
     85  1.4  rillig .    error
     86  1.4  rillig .  endif
     87  1.4  rillig varname=	varvalue
     88  1.4  rillig .  if ${DOLLARS} != "varvalue"
     89  1.4  rillig .    error
     90  1.4  rillig .  endif
     91  1.4  rillig .  undef varname
     92  1.4  rillig .endif
     93  1.2  rillig dollars_stage_2:
     94  1.2  rillig 	@echo "$@: env MAKEFLAGS=<$$MAKEFLAGS>"
     95  1.2  rillig 	@echo '$@: dollars=<'${DOLLARS:Q}'>'
     96  1.2  rillig 	@echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>'
     97  1.2  rillig 	@${MAKE} -f ${MAKEFILE} dollars_stage_3
     98  1.2  rillig 
     99  1.2  rillig dollars_stage_3:
    100  1.2  rillig 	@echo "$@: env MAKEFLAGS=<$$MAKEFLAGS>"
    101  1.2  rillig 	@echo '$@: dollars=<'${DOLLARS:Uundefined:Q}'>'
    102  1.2  rillig 	@echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>'
    103  1.2  rillig 
    104  1.2  rillig 
    105  1.2  rillig # Demonstrates in which exact order the MAKEFLAGS are built together from the
    106  1.2  rillig # parent MAKEFLAGS and the flags from the command line, in particular that
    107  1.2  rillig # variable assignments are passed at the end, after the options.
    108  1.2  rillig append_stage_0:
    109  1.2  rillig 	@echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>'
    110  1.2  rillig 	@${MAKE} -Dbefore-0 -f ${MAKEFILE} append_stage_1 VAR0=value -Dafter-0
    111  1.2  rillig 
    112  1.2  rillig append_stage_1:
    113  1.2  rillig 	@echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>'
    114  1.2  rillig 	@${MAKE} -Dbefore-1 -f ${MAKEFILE} append_stage_2 VAR1=value -Dafter-1
    115  1.2  rillig 
    116  1.2  rillig append_stage_2:
    117  1.2  rillig 	@echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>'
    118  1.2  rillig 	@${MAKE} -Dbefore-2 -f ${MAKEFILE} append_stage_3 VAR2=value -Dafter-2
    119  1.2  rillig 
    120  1.2  rillig append_stage_3:
    121  1.2  rillig 	@echo '$@: MAKEFLAGS=<'${MAKEFLAGS:Q}'>'
    122  1.5  rillig 
    123  1.5  rillig 
    124  1.5  rillig # Demonstrates the implementation details of 'MAKEFLAGS', in particular that
    125  1.5  rillig # it is an environment variable rather than a global variable.
    126  1.5  rillig override_stage_0:
    127  1.5  rillig 	@${MAKE} -f ${MAKEFILE} STAGE=1 VAR=value override_stage_1
    128  1.5  rillig 
    129  1.5  rillig .if make(override_stage_1)
    130  1.5  rillig # While parsing the makefiles, 'MAKEFLAGS' is the value of the environment
    131  1.5  rillig # variable, in this case provided by stage 0.
    132  1.5  rillig .  if ${MAKEFLAGS:M*} != "-r -k"
    133  1.5  rillig .    error
    134  1.5  rillig .  endif
    135  1.5  rillig MAKEFLAGS=	overridden	# temporarily override it
    136  1.5  rillig .  if ${MAKEFLAGS} != "overridden"
    137  1.5  rillig .    error
    138  1.5  rillig .  endif
    139  1.5  rillig .undef MAKEFLAGS		# make the environment variable visible again
    140  1.5  rillig .  if ${MAKEFLAGS:M*} != "-r -k"
    141  1.5  rillig .    error
    142  1.5  rillig .  endif
    143  1.5  rillig .endif
    144  1.5  rillig override_stage_1:
    145  1.5  rillig 	@echo '$@: run MAKEFLAGS=<'${MAKEFLAGS:Q}'>'
    146  1.5  rillig 	@${MAKE} -f ${MAKEFILE} STAGE=2 override_stage_2
    147  1.5  rillig 
    148  1.5  rillig override_stage_2:
    149  1.5  rillig 	@echo '$@: STAGE=<${STAGE}> VAR=<${VAR}>'
    150