make(1): add tests and tutorial for the ?= assignment operator
This commit is contained in:
parent
16f88d4a62
commit
1e55774c0d
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: mi,v 1.984 2020/12/07 07:51:25 rillig Exp $
|
||||
# $NetBSD: mi,v 1.985 2020/12/07 21:35:43 rillig Exp $
|
||||
#
|
||||
# Note: don't delete entries from here - mark them as "obsolete" instead.
|
||||
#
|
||||
|
@ -5263,8 +5263,8 @@
|
|||
./usr/tests/usr.bin/make/unit-tests/posix.mk tests-usr.bin-tests compattestfile,atf
|
||||
./usr/tests/usr.bin/make/unit-tests/posix1.exp tests-usr.bin-tests compattestfile,atf
|
||||
./usr/tests/usr.bin/make/unit-tests/posix1.mk tests-usr.bin-tests compattestfile,atf
|
||||
./usr/tests/usr.bin/make/unit-tests/qequals.exp tests-usr.bin-tests compattestfile,atf
|
||||
./usr/tests/usr.bin/make/unit-tests/qequals.mk tests-usr.bin-tests compattestfile,atf
|
||||
./usr/tests/usr.bin/make/unit-tests/qequals.exp tests-obsolete obsolete,atf
|
||||
./usr/tests/usr.bin/make/unit-tests/qequals.mk tests-obsolete obsolete,atf
|
||||
./usr/tests/usr.bin/make/unit-tests/recursive.exp tests-usr.bin-tests compattestfile,atf
|
||||
./usr/tests/usr.bin/make/unit-tests/recursive.mk tests-usr.bin-tests compattestfile,atf
|
||||
./usr/tests/usr.bin/make/unit-tests/sh-dots.exp tests-usr.bin-tests compattestfile,atf
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
# $NetBSD: Makefile,v 1.238 2020/12/07 01:32:04 rillig Exp $
|
||||
# $NetBSD: Makefile,v 1.239 2020/12/07 21:35:43 rillig Exp $
|
||||
#
|
||||
# Unit tests for make(1)
|
||||
#
|
||||
|
@ -257,7 +257,6 @@ TESTS+= parse-var
|
|||
TESTS+= phony-end
|
||||
TESTS+= posix
|
||||
TESTS+= # posix1 # broken by reverting POSIX changes
|
||||
TESTS+= qequals
|
||||
TESTS+= recursive
|
||||
TESTS+= sh
|
||||
TESTS+= sh-dots
|
||||
|
|
|
@ -1,2 +0,0 @@
|
|||
V.i386 ?= OK
|
||||
exit status 0
|
|
@ -1,8 +0,0 @@
|
|||
# $NetBSD: qequals.mk,v 1.3 2020/10/24 08:50:17 rillig Exp $
|
||||
|
||||
M= i386
|
||||
V.i386= OK
|
||||
V.$M?= bug
|
||||
|
||||
all:
|
||||
@echo 'V.$M ?= ${V.$M}'
|
|
@ -1,9 +1,77 @@
|
|||
# $NetBSD: var-op-default.mk,v 1.2 2020/08/16 14:25:16 rillig Exp $
|
||||
# $NetBSD: var-op-default.mk,v 1.3 2020/12/07 21:35:43 rillig Exp $
|
||||
#
|
||||
# Tests for the ?= variable assignment operator, which only assigns
|
||||
# if the variable is still undefined.
|
||||
|
||||
# TODO: Implementation
|
||||
# The variable VAR is not defined yet. Therefore it gets the default value
|
||||
# from the variable assignment.
|
||||
VAR?= default value
|
||||
.if ${VAR} != "default value"
|
||||
. error
|
||||
.endif
|
||||
|
||||
# At this point, the variable 'VAR' is already defined. The '?=' therefore
|
||||
# ignores the new variable value, preserving the previous "default value".
|
||||
VAR?= ignored
|
||||
.if ${VAR} != "default value"
|
||||
. error
|
||||
.endif
|
||||
|
||||
# The '?=' operator only checks whether the variable is defined or not.
|
||||
# An empty variable is defined, therefore the '?=' operator does nothing.
|
||||
EMPTY= # empty
|
||||
EMPTY?= ignored
|
||||
.if ${EMPTY} != ""
|
||||
. error
|
||||
.endif
|
||||
|
||||
# The .for loop is described in the manual page as if it would operate on
|
||||
# variables. This is not entirely true. Instead, each occurrence of an
|
||||
# expression $i or ${i} or ${i:...} is substituted with ${:Uloop-value}.
|
||||
# This comes very close to the description, the only difference is that
|
||||
# there is never an actual variable named 'i' involved.
|
||||
#
|
||||
# Because there is not really a variable named 'i', the '?=' operator
|
||||
# performs the variable assignment, resulting in $i == "default".
|
||||
.for i in loop-value
|
||||
i?= default
|
||||
.endfor
|
||||
.if ${i} != "default"
|
||||
. error
|
||||
.endif
|
||||
|
||||
# At the point where the '?=' operator checks whether the variable exists,
|
||||
# it expands the variable name exactly once. Therefore both 'VAR.param'
|
||||
# and 'VAR.${param}' expand to 'VAR.param', and the second '?=' assignment
|
||||
# has no effect.
|
||||
#
|
||||
# Since 2000.05.11.07.43.42 it has been possible to use nested variable
|
||||
# expressions in variable names, which made make much more versatile.
|
||||
# On 2008.03.31.00.12.21, this particular case of the '?=' operator has been
|
||||
# fixed. Before, the '?=' operator had not expanded the variable name
|
||||
# 'VAR.${:Uparam}' to see whether the variable already existed. Since that
|
||||
# variable didn't exist (and variables with '$' in their name are particularly
|
||||
# fragile), the variable assignment with "not used" was performed, and only
|
||||
# during that, the variable name was expanded.
|
||||
VAR.param= already defined
|
||||
VAR.${:Uparam}?= not used
|
||||
.if ${VAR.param} != "already defined"
|
||||
. error
|
||||
.endif
|
||||
|
||||
# Now demonstrate that the variable name is indeed expanded exactly once.
|
||||
# This is tricky to measure correctly since there are many inconsistencies
|
||||
# in and around the code that expands variable expressions in the various
|
||||
# places where variable expressions can occur. If in doubt, enable the
|
||||
# following debug flags to see what happens:
|
||||
#.MAKEFLAGS: -dcpv
|
||||
EXPAND_NAME= EXPAND.$$$$ # The full variable name is EXPAND.$$
|
||||
PARAM= $$$$
|
||||
EXPAND.${PARAM}?= value with param
|
||||
.if ${${EXPAND_NAME}} != "value with param"
|
||||
. error
|
||||
.endif
|
||||
.MAKEFLAGS: -d0
|
||||
|
||||
all:
|
||||
@:;
|
||||
|
|
Loading…
Reference in New Issue