diff --git a/usr.bin/make/unit-tests/directive-export-gmake.exp b/usr.bin/make/unit-tests/directive-export-gmake.exp index cf08a0443acc..c37d3b2d8591 100644 --- a/usr.bin/make/unit-tests/directive-export-gmake.exp +++ b/usr.bin/make/unit-tests/directive-export-gmake.exp @@ -1,5 +1,6 @@ make: "directive-export-gmake.mk" line 71: Invalid line 'export VAR=${:U1}', expanded to 'export VAR=1' make: "directive-export-gmake.mk" line 85: 16:00:00 +make: "directive-export-gmake.mk" line 92: Variable/Value missing from "export" make: Fatal errors encountered -- cannot continue make: stopped in unit-tests exit status 1 diff --git a/usr.bin/make/unit-tests/directive-export-gmake.mk b/usr.bin/make/unit-tests/directive-export-gmake.mk index f7a617ab7553..6734704d3357 100644 --- a/usr.bin/make/unit-tests/directive-export-gmake.mk +++ b/usr.bin/make/unit-tests/directive-export-gmake.mk @@ -1,4 +1,4 @@ -# $NetBSD: directive-export-gmake.mk,v 1.7 2023/08/20 20:48:32 rillig Exp $ +# $NetBSD: directive-export-gmake.mk,v 1.8 2023/11/19 09:45:19 rillig Exp $ # # Tests for the export directive (without leading dot), as in GNU make. @@ -83,3 +83,24 @@ INDIRECT_TZ= ${:UAmerica/Los_Angeles} export TZ=${INDIRECT_TZ} # expect+1: 16:00:00 .info ${%T:L:localtime=86400} + + +# The '=' must be present in the unexpanded line, it cannot be generated by +# an expression. +EQ= = +# expect+1: Variable/Value missing from "export" +export EQ_VAR${EQ}eq-value +.if ${:!env!:MEQ_VAR=*} +. error +.endif + + +# The variable name must be given directly, it is not expanded. The name of +# the exported variable thus starts with a '$', and that name may be filtered +# out by the platform. +INDIRECT_NAME= I_NAME +INDIRECT_VALUE= indirect value +export ${INDIRECT_NAME}=${INDIRECT_VALUE} +.if ${:!env!:MI_NAME=*} +. error +.endif diff --git a/usr.bin/make/unit-tests/directive-export.exp b/usr.bin/make/unit-tests/directive-export.exp index a5d706e58f32..774a814570e3 100644 --- a/usr.bin/make/unit-tests/directive-export.exp +++ b/usr.bin/make/unit-tests/directive-export.exp @@ -1,4 +1,4 @@ -make: "directive-export.mk" line 50: 00:00:00 -make: "directive-export.mk" line 55: 00:00:00 -make: "directive-export.mk" line 58: 16:00:00 +make: "directive-export.mk" line 56: 00:00:00 +make: "directive-export.mk" line 61: 00:00:00 +make: "directive-export.mk" line 64: 16:00:00 exit status 0 diff --git a/usr.bin/make/unit-tests/directive-export.mk b/usr.bin/make/unit-tests/directive-export.mk index d46b1dc01f27..08109814bcfd 100644 --- a/usr.bin/make/unit-tests/directive-export.mk +++ b/usr.bin/make/unit-tests/directive-export.mk @@ -1,4 +1,4 @@ -# $NetBSD: directive-export.mk,v 1.9 2023/08/20 20:48:32 rillig Exp $ +# $NetBSD: directive-export.mk,v 1.10 2023/11/19 09:45:19 rillig Exp $ # # Tests for the .export directive. # @@ -35,7 +35,13 @@ VAR= value $$ ${INDIRECT} .export ${:U} -# Trigger the "This isn't going to end well" in ExportVarEnv. +# Before a child process is started, whether for the '!=' assignment operator +# or for the ':sh' modifier, all variables that were marked for being exported +# are expanded and then exported. If expanding such a variable requires +# running a child command, the marked-as-exported variables would need to be +# exported first, ending in an endless loop. To avoid this endless loop, +# don't export the variables while preparing a child process, see +# ExportVarEnv. EMPTY_SHELL= ${:sh} .export EMPTY_SHELL # only marked for export at this point _!= :;: # Force the variable to be actually exported. diff --git a/usr.bin/make/var.c b/usr.bin/make/var.c index 65728d3373a3..53a4f034b130 100644 --- a/usr.bin/make/var.c +++ b/usr.bin/make/var.c @@ -1,4 +1,4 @@ -/* $NetBSD: var.c,v 1.1069 2023/11/18 20:19:08 rillig Exp $ */ +/* $NetBSD: var.c,v 1.1070 2023/11/19 09:45:19 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -139,7 +139,7 @@ #include "metachar.h" /* "@(#)var.c 8.3 (Berkeley) 3/19/94" */ -MAKE_RCSID("$NetBSD: var.c,v 1.1069 2023/11/18 20:19:08 rillig Exp $"); +MAKE_RCSID("$NetBSD: var.c,v 1.1070 2023/11/19 09:45:19 rillig Exp $"); /* * Variables are defined using one of the VAR=value assignments. Their @@ -615,13 +615,8 @@ ExportVarEnv(Var *v) return true; } - if (v->inUse) { - /* - * We recursed while exporting in a child. - * This isn't going to end well, just skip it. - */ - return false; - } + if (v->inUse) + return false; /* see EMPTY_SHELL in directive-export.mk */ /* XXX: name is injected without escaping it */ expr = str_concat3("${", name, "}");