xref: /freebsd/contrib/bmake/unit-tests/dep-var.mk (revision e32fecd0c2c3ee37c47ee100f169e7eb0282a873)
1# $NetBSD: dep-var.mk,v 1.7 2023/02/13 21:01:46 rillig Exp $
2#
3# Tests for variable references in dependency declarations.
4#
5# Uh oh, this feels so strange that probably nobody uses it. But it seems to
6# be the only way to reach the lower half of SuffExpandChildren.
7
8.MAKEFLAGS: -dv
9
10# expect: Var_Parse: ${UNDEF1} (eval-defined)
11# Even though undefined expressions should lead to errors, no error message is
12# generated for this line.  The variable expression ${UNDEF1} simply expands
13# to an empty string.
14all: ${UNDEF1}
15
16# Using a double dollar in order to circumvent immediate variable expansion
17# feels like unintended behavior.  At least the manual page says nothing at
18# all about defined or undefined variables in dependency lines.
19#
20# At the point where the expression ${DEF2} is expanded, the variable DEF2
21# is defined, so everything's fine.
22all: $${DEF2} a-$${DEF2}-b
23
24# This variable is not defined at all.
25# XXX: The -dv log says later when expanding the sources of 'all':
26#	Var_Parse: ${UNDEF3} (eval-defined)
27# but no error message is generated for this line, just like for UNDEF1.
28# The variable expression ${UNDEF3} simply expands to an empty string.
29all: $${UNDEF3}
30
31# Try out how many levels of indirection are really expanded in dependency
32# lines.
33#
34# The first level of indirection is the $$ in the dependency line.
35# When the dependency line is parsed, it is resolved to the string
36# "${INDIRECT_1}".  At this point, the dollar is just an ordinary character,
37# waiting to be expanded at some later point.
38#
39# Later, in SuffExpandChildren, that expression is expanded again by calling
40# Var_Parse, and this time, the result is the string "1-2-${INDIRECT_2}-2-1".
41#
42# This string is not expanded anymore by Var_Parse.  But there is another
43# effect.  Now DirExpandCurly comes into play and expands the curly braces
44# in this filename pattern, resulting in the string "1-2-$INDIRECT_2-2-1".
45# As of 2020-09-03, the test dir.mk contains further details on this topic.
46#
47# Finally, this string is assigned to the local ${.TARGET} variable.  This
48# variable is expanded when the shell command is generated.  At that point,
49# the $I is expanded.  Since the variable I is not defined, it expands to
50# the empty string.  This way, the final output is the string
51# "1-2-NDIRECT_2-2-1", which differs from the actual name of the target.
52# For exactly this reason, it is not recommended to use dollar signs in
53# target names.
54#
55# The number of actual expansions is way more than one might expect,
56# therefore this feature is probably not widely used.
57#
58all: 1-$${INDIRECT_1}-1
59INDIRECT_1=	2-$${INDIRECT_2}-2
60INDIRECT_2=	3-$${INDIRECT_3}-3
61INDIRECT_3=	indirect
62
63UNDEF1=	undef1
64DEF2=	def2
65
66# Cover the code in SuffExpandChildren that deals with malformed variable
67# expressions.
68#
69# This seems to be an edge case that never happens in practice, and it would
70# probably be appropriate to just error out in such a case.
71#
72# To trigger this piece of code, the variable name must contain "$)" or "$:"
73# or "$)" or "$$".  Using "$:" does not work since the dependency line is
74# fully expanded before parsing, therefore any ':' in a target or source name
75# would be interpreted as a dependency operator instead.
76all: $$$$)
77
78# The $$INDIRECT in the following line is treated like the dependency of the
79# "all" target, that is, the "$$I" is first expanded to "$I", and in a second
80# round of expansion, the "$I" expands to nothing since the variable "I" is
81# undefined.
82#
83# Since 2020-09-13, this generates a parse error in lint mode (-dL), but not
84# in normal mode since ParseDependency does not handle any errors after
85# calling Var_Parse.
86# expect: Var_Parse: ${:U\$)}: (eval-defined)
87# expect: Var_Parse: $INDIRECT_2-2-1 $): (parse-only)
88# expect: Var_Parse: $): (parse-only)
89undef1 def2 a-def2-b 1-2-$$INDIRECT_2-2-1 ${:U\$)}:
90	@echo ${.TARGET:Q}
91
92.MAKEFLAGS: -d0
93
94# XXX: Why is the exit status still 0, even though Parse_Error is called
95# with PARSE_FATAL in SuffExpandChildren?
96