1# $NetBSD: var-op-default.mk,v 1.3 2020/12/07 21:35:43 rillig Exp $ 2# 3# Tests for the ?= variable assignment operator, which only assigns 4# if the variable is still undefined. 5 6# The variable VAR is not defined yet. Therefore it gets the default value 7# from the variable assignment. 8VAR?= default value 9.if ${VAR} != "default value" 10. error 11.endif 12 13# At this point, the variable 'VAR' is already defined. The '?=' therefore 14# ignores the new variable value, preserving the previous "default value". 15VAR?= ignored 16.if ${VAR} != "default value" 17. error 18.endif 19 20# The '?=' operator only checks whether the variable is defined or not. 21# An empty variable is defined, therefore the '?=' operator does nothing. 22EMPTY= # empty 23EMPTY?= ignored 24.if ${EMPTY} != "" 25. error 26.endif 27 28# The .for loop is described in the manual page as if it would operate on 29# variables. This is not entirely true. Instead, each occurrence of an 30# expression $i or ${i} or ${i:...} is substituted with ${:Uloop-value}. 31# This comes very close to the description, the only difference is that 32# there is never an actual variable named 'i' involved. 33# 34# Because there is not really a variable named 'i', the '?=' operator 35# performs the variable assignment, resulting in $i == "default". 36.for i in loop-value 37i?= default 38.endfor 39.if ${i} != "default" 40. error 41.endif 42 43# At the point where the '?=' operator checks whether the variable exists, 44# it expands the variable name exactly once. Therefore both 'VAR.param' 45# and 'VAR.${param}' expand to 'VAR.param', and the second '?=' assignment 46# has no effect. 47# 48# Since 2000.05.11.07.43.42 it has been possible to use nested variable 49# expressions in variable names, which made make much more versatile. 50# On 2008.03.31.00.12.21, this particular case of the '?=' operator has been 51# fixed. Before, the '?=' operator had not expanded the variable name 52# 'VAR.${:Uparam}' to see whether the variable already existed. Since that 53# variable didn't exist (and variables with '$' in their name are particularly 54# fragile), the variable assignment with "not used" was performed, and only 55# during that, the variable name was expanded. 56VAR.param= already defined 57VAR.${:Uparam}?= not used 58.if ${VAR.param} != "already defined" 59. error 60.endif 61 62# Now demonstrate that the variable name is indeed expanded exactly once. 63# This is tricky to measure correctly since there are many inconsistencies 64# in and around the code that expands variable expressions in the various 65# places where variable expressions can occur. If in doubt, enable the 66# following debug flags to see what happens: 67#.MAKEFLAGS: -dcpv 68EXPAND_NAME= EXPAND.$$$$ # The full variable name is EXPAND.$$ 69PARAM= $$$$ 70EXPAND.${PARAM}?= value with param 71.if ${${EXPAND_NAME}} != "value with param" 72. error 73.endif 74.MAKEFLAGS: -d0 75 76all: 77 @:; 78