1 # $NetBSD: var-op-default.mk,v 1.5 2023/11/19 22:32:44 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. 8 VAR?= 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". 15 VAR?= 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. 22 EMPTY= # empty 23 EMPTY?= 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 37 i?= 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 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. 56 VAR.param= already defined 57 VAR.${: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 expressions in the various 65 # places where expressions can occur. If in doubt, enable the 66 # following debug flags to see what happens: 67 #.MAKEFLAGS: -dcpv 68 EXPAND_NAME= EXPAND.$$$$ # The full variable name is EXPAND.$$ 69 PARAM= $$$$ 70 EXPAND.${PARAM}?= value with param 71 .if ${${EXPAND_NAME}} != "value with param" 72 . error 73 .endif 74 .MAKEFLAGS: -d0 75 76 all: 77 @:; 78