Module Name: src Committed By: rillig Date: Tue Aug 27 04:52:14 UTC 2024
Modified Files: src/usr.bin/make: main.c make.h var.c src/usr.bin/make/unit-tests: var-recursive.exp var-recursive.mk Log Message: make: treat recursive variables non-fatally A recursive variable is no worse than an unknown modifier, so treat them in the same way by continuing parsing until the end of the makefile. To generate a diff of this commit: cvs rdiff -u -r1.633 -r1.634 src/usr.bin/make/main.c cvs rdiff -u -r1.345 -r1.346 src/usr.bin/make/make.h cvs rdiff -u -r1.1137 -r1.1138 src/usr.bin/make/var.c cvs rdiff -u -r1.10 -r1.11 src/usr.bin/make/unit-tests/var-recursive.exp cvs rdiff -u -r1.7 -r1.8 src/usr.bin/make/unit-tests/var-recursive.mk Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/usr.bin/make/main.c diff -u src/usr.bin/make/main.c:1.633 src/usr.bin/make/main.c:1.634 --- src/usr.bin/make/main.c:1.633 Sun Aug 25 20:44:31 2024 +++ src/usr.bin/make/main.c Tue Aug 27 04:52:14 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: main.c,v 1.633 2024/08/25 20:44:31 rillig Exp $ */ +/* $NetBSD: main.c,v 1.634 2024/08/27 04:52:14 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -111,7 +111,7 @@ #include "trace.h" /* "@(#)main.c 8.3 (Berkeley) 3/19/94" */ -MAKE_RCSID("$NetBSD: main.c,v 1.633 2024/08/25 20:44:31 rillig Exp $"); +MAKE_RCSID("$NetBSD: main.c,v 1.634 2024/08/27 04:52:14 rillig Exp $"); #if defined(MAKE_NATIVE) __COPYRIGHT("@(#) Copyright (c) 1988, 1989, 1990, 1993 " "The Regents of the University of California. " @@ -1859,13 +1859,6 @@ Error(const char *fmt, ...) main_errors++; } -void -WaitForJobs(void) -{ - if (jobsRunning) - Job_Wait(); -} - /* * Wait for any running jobs to finish, then produce an error message, * finally exit immediately. @@ -1878,7 +1871,8 @@ Fatal(const char *fmt, ...) { va_list ap; - WaitForJobs(); + if (jobsRunning) + Job_Wait(); (void)fflush(stdout); fprintf(stderr, "%s: ", progname); Index: src/usr.bin/make/make.h diff -u src/usr.bin/make/make.h:1.345 src/usr.bin/make/make.h:1.346 --- src/usr.bin/make/make.h:1.345 Sun Aug 25 20:44:31 2024 +++ src/usr.bin/make/make.h Tue Aug 27 04:52:14 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: make.h,v 1.345 2024/08/25 20:44:31 rillig Exp $ */ +/* $NetBSD: make.h,v 1.346 2024/08/27 04:52:14 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -864,7 +864,6 @@ char *getTmpdir(void) MAKE_ATTR_USE; bool ParseBoolean(const char *, bool) MAKE_ATTR_USE; const char *cached_realpath(const char *, char *); bool GetBooleanExpr(const char *, bool); -void WaitForJobs(void); /* parse.c */ extern int parseErrors; Index: src/usr.bin/make/var.c diff -u src/usr.bin/make/var.c:1.1137 src/usr.bin/make/var.c:1.1138 --- src/usr.bin/make/var.c:1.1137 Sun Aug 25 20:44:31 2024 +++ src/usr.bin/make/var.c Tue Aug 27 04:52:14 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: var.c,v 1.1137 2024/08/25 20:44:31 rillig Exp $ */ +/* $NetBSD: var.c,v 1.1138 2024/08/27 04:52:14 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -129,7 +129,7 @@ #include "trace.h" /* "@(#)var.c 8.3 (Berkeley) 3/19/94" */ -MAKE_RCSID("$NetBSD: var.c,v 1.1137 2024/08/25 20:44:31 rillig Exp $"); +MAKE_RCSID("$NetBSD: var.c,v 1.1138 2024/08/27 04:52:14 rillig Exp $"); /* * Variables are defined using one of the VAR=value assignments. Their @@ -4573,16 +4573,13 @@ Var_Parse(const char **pp, GNode *scope, expr.name = v->name.str; if (v->inUse && VarEvalMode_ShouldEval(emode)) { - if (scope->fname != NULL) { - fprintf(stderr, "In a command near "); - PrintLocation(stderr, false, scope); - } - WaitForJobs(); Parse_Error(PARSE_FATAL, "Variable %s is recursive.", v->name.str); - PrintOnError(NULL, "\n"); - Trace_Log(MAKEERROR, NULL); - exit(2); /* Not 1 so -q can distinguish error */ + FStr_Done(&val); + if (*p != '\0') + p++; + *pp = p; + return FStr_InitRefer(var_Error); } /* Index: src/usr.bin/make/unit-tests/var-recursive.exp diff -u src/usr.bin/make/unit-tests/var-recursive.exp:1.10 src/usr.bin/make/unit-tests/var-recursive.exp:1.11 --- src/usr.bin/make/unit-tests/var-recursive.exp:1.10 Sun Aug 25 20:44:31 2024 +++ src/usr.bin/make/unit-tests/var-recursive.exp Tue Aug 27 04:52:14 2024 @@ -1,23 +1,20 @@ -make: "var-recursive.mk" line 21: still there -make: "var-recursive.mk" line 23: while evaluating variable "DIRECT" with value "${DIRECT}": Variable DIRECT is recursive. +make: "var-recursive.mk" line 11: while evaluating variable "DIRECT" with value "${DIRECT}": Variable DIRECT is recursive. in directory <curdir> - -make: stopped in unit-tests -sub-exit status 2 -make: "var-recursive.mk" line 31: while evaluating variable "INDIRECT1" with value "${INDIRECT2}": while evaluating variable "INDIRECT2" with value "${INDIRECT1}": Variable INDIRECT1 is recursive. +make: "var-recursive.mk" line 11: <> +make: "var-recursive.mk" line 19: while evaluating variable "INDIRECT1" with value "${INDIRECT2}": while evaluating variable "INDIRECT2" with value "${INDIRECT1}": Variable INDIRECT1 is recursive. in directory <curdir> - -make: stopped in unit-tests -sub-exit status 2 -make: "var-recursive.mk" line 39: ok -make: "var-recursive.mk" line 48: while evaluating variable "V" with value "$V": Variable V is recursive. +make: "var-recursive.mk" line 19: <> +make: "var-recursive.mk" line 26: <ok> +make: "var-recursive.mk" line 34: while evaluating variable "MODIFIERS" with value "${MODIFIERS:Mpattern}": Variable MODIFIERS is recursive. in directory <curdir> - -make: stopped in unit-tests -sub-exit status 2 +make: "var-recursive.mk" line 34: <Mpattern}> +make: "var-recursive.mk" line 43: while evaluating variable "V" with value "$V": Variable V is recursive. + in directory <curdir> +make: "var-recursive.mk" line 43: <> +make: Fatal errors encountered -- cannot continue +make: stopped making "loadtime" in unit-tests +sub-exit status 1 : OK -In a command near "var-recursive.mk" line 60: make[1]: in target "target": while evaluating variable "VAR" with value "${VAR}": Variable VAR is recursive. - -make: stopped making "target" in unit-tests +make: in target "runtime": while evaluating variable "VAR" with value "${VAR}": Variable VAR is recursive. sub-exit status 2 exit status 0 Index: src/usr.bin/make/unit-tests/var-recursive.mk diff -u src/usr.bin/make/unit-tests/var-recursive.mk:1.7 src/usr.bin/make/unit-tests/var-recursive.mk:1.8 --- src/usr.bin/make/unit-tests/var-recursive.mk:1.7 Sun Aug 25 20:44:31 2024 +++ src/usr.bin/make/unit-tests/var-recursive.mk Tue Aug 27 04:52:14 2024 @@ -1,66 +1,64 @@ -# $NetBSD: var-recursive.mk,v 1.7 2024/08/25 20:44:31 rillig Exp $ +# $NetBSD: var-recursive.mk,v 1.8 2024/08/27 04:52:14 rillig Exp $ # -# Tests for expressions that refer to themselves and thus -# cannot be evaluated. +# Tests for expressions that refer to themselves and thus cannot be +# evaluated, as that would lead to an endless loop. -TESTS= direct indirect conditional short target +.if make(loadtime) -# Since make exits immediately when it detects a recursive expression, -# the actual tests are run in sub-makes. -TEST?= # none -.if ${TEST} == "" -all: -.for test in ${TESTS} - @${.MAKE} -f ${MAKEFILE} TEST=${test} || echo "sub-exit status $$?" -.endfor - -.elif ${TEST} == direct - -DIRECT= ${DIRECT} # Defining a recursive variable is not yet an error. -# expect+1: still there -. info still there # Therefore this line is printed. -# expect+1: while evaluating variable "DIRECT" with value "${DIRECT}": Variable DIRECT is recursive. -. info ${DIRECT} # But expanding the variable is an error. +DIRECT= ${DIRECT} # Defining a recursive variable is not an error. +# expect+2: while evaluating variable "DIRECT" with value "${DIRECT}": Variable DIRECT is recursive. +# expect+1: <> +. info <${DIRECT}> # But expanding such a variable is an error. -.elif ${TEST} == indirect # The chain of variables that refer to each other may be long. INDIRECT1= ${INDIRECT2} INDIRECT2= ${INDIRECT1} -# expect+1: while evaluating variable "INDIRECT1" with value "${INDIRECT2}": while evaluating variable "INDIRECT2" with value "${INDIRECT1}": Variable INDIRECT1 is recursive. -. info ${INDIRECT1} +# expect+2: while evaluating variable "INDIRECT1" with value "${INDIRECT2}": while evaluating variable "INDIRECT2" with value "${INDIRECT1}": Variable INDIRECT1 is recursive. +# expect+1: <> +. info <${INDIRECT1}> -.elif ${TEST} == conditional # The variable refers to itself, but only in the branch of a condition that -# is never satisfied and is thus not evaluated. +# is not satisfied and is thus not evaluated. CONDITIONAL= ${1:?ok:${CONDITIONAL}} -# expect+1: ok -. info ${CONDITIONAL} +# expect+1: <ok> +. info <${CONDITIONAL}> + + +# An expression with modifiers is skipped halfway. This can lead to wrong +# follow-up error messages, but recursive variables occur seldom. +MODIFIERS= ${MODIFIERS:Mpattern} +# expect+2: while evaluating variable "MODIFIERS" with value "${MODIFIERS:Mpattern}": Variable MODIFIERS is recursive. +# expect+1: <Mpattern}> +. info <${MODIFIERS}> -.elif ${TEST} == short # Short variable names can be expanded using the short-hand $V notation, # which takes a different code path in Var_Parse for parsing the variable # name. Ensure that these are checked as well. V= $V -# expect+1: while evaluating variable "V" with value "$V": Variable V is recursive. -. info $V +# expect+2: while evaluating variable "V" with value "$V": Variable V is recursive. +# expect+1: <> +. info <$V> -.elif ${TEST} == target +.elif make(runtime) # If a recursive variable is accessed in a command of a target, the makefiles -# are not parsed anymore, so there is no location information from the -# .includes and .for directives. In such a case, use the location of the last +# have already been fully parsed, so there is no location information from the +# .include and .for directives. In such a case, use the location of the last # command of the target to provide at least a hint to the location. VAR= ${VAR} -target: +runtime: : OK - : ${VAR} +# expect: make: in target "runtime": while evaluating variable "VAR" with value "${VAR}": Variable VAR is recursive. + : <${VAR}> : OK .else -. error Unknown test "${TEST}" -.endif all: + @${MAKE} -f ${MAKEFILE} loadtime || echo "sub-exit status $$?" + @${MAKE} -f ${MAKEFILE} runtime || echo "sub-exit status $$?" + +.endif