Module Name: src Committed By: rillig Date: Sat Mar 22 12:23:00 UTC 2025
Modified Files: src/usr.bin/make: var.c src/usr.bin/make/unit-tests: varname-dot-make-level.exp varname-dot-make-level.mk Log Message: make: ignore attempts to override a read-only global with the same value Up to NetBSD 9, make passed around the internal variable .MAKE.LEVEL.ENV via MAKEFLAGS. Allow these old versions of make to coexist with newer versions of make. See unit-tests/varname-dot-make-level.mk for details. Fixes PR pkg/59184. To generate a diff of this commit: cvs rdiff -u -r1.1144 -r1.1145 src/usr.bin/make/var.c cvs rdiff -u -r1.4 -r1.5 \ src/usr.bin/make/unit-tests/varname-dot-make-level.exp cvs rdiff -u -r1.5 -r1.6 \ src/usr.bin/make/unit-tests/varname-dot-make-level.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/var.c diff -u src/usr.bin/make/var.c:1.1144 src/usr.bin/make/var.c:1.1145 --- src/usr.bin/make/var.c:1.1144 Sat Jan 11 21:21:33 2025 +++ src/usr.bin/make/var.c Sat Mar 22 12:23:00 2025 @@ -1,4 +1,4 @@ -/* $NetBSD: var.c,v 1.1144 2025/01/11 21:21:33 rillig Exp $ */ +/* $NetBSD: var.c,v 1.1145 2025/03/22 12:23:00 rillig Exp $ */ /* * Copyright (c) 1988, 1989, 1990, 1993 @@ -128,7 +128,7 @@ #include "metachar.h" /* "@(#)var.c 8.3 (Berkeley) 3/19/94" */ -MAKE_RCSID("$NetBSD: var.c,v 1.1144 2025/01/11 21:21:33 rillig Exp $"); +MAKE_RCSID("$NetBSD: var.c,v 1.1145 2025/03/22 12:23:00 rillig Exp $"); /* * Variables are defined using one of the VAR=value assignments. Their @@ -1037,7 +1037,13 @@ Var_SetWithFlags(GNode *scope, const cha * See ExistsInCmdline. */ Var *gl = VarFind(name, SCOPE_GLOBAL, false); - if (gl != NULL && gl->readOnlyLoud) + if (gl != NULL && strcmp(gl->val.data, val) == 0) { + DEBUG3(VAR, + "%s: ignoring to override the global " + "'%s = %s' from a command line variable " + "as the value wouldn't change\n", + scope->name, name, val); + } else if (gl != NULL && gl->readOnlyLoud) Parse_Error(PARSE_FATAL, "Cannot override " "read-only global variable \"%s\" " Index: src/usr.bin/make/unit-tests/varname-dot-make-level.exp diff -u src/usr.bin/make/unit-tests/varname-dot-make-level.exp:1.4 src/usr.bin/make/unit-tests/varname-dot-make-level.exp:1.5 --- src/usr.bin/make/unit-tests/varname-dot-make-level.exp:1.4 Sat Nov 23 22:59:51 2024 +++ src/usr.bin/make/unit-tests/varname-dot-make-level.exp Sat Mar 22 12:23:00 2025 @@ -1,12 +1,11 @@ level 1: variable 0, env 1 level 2: variable 1, env 2 level 3: variable 2, env 3 +: set-env-same +ok +: set-env-different make: Cannot override read-only global variable ".MAKE.LEVEL.ENV" with a command line variable make: Fatal errors encountered -- cannot continue -make: stopped in unit-tests -*** Error code 1 (continuing) -`all' not remade because of errors. - -Stop. -make: stopped making "all" in unit-tests -exit status 1 +make: stopped making "ok" in unit-tests +set-env-different: exit 1 +exit status 0 Index: src/usr.bin/make/unit-tests/varname-dot-make-level.mk diff -u src/usr.bin/make/unit-tests/varname-dot-make-level.mk:1.5 src/usr.bin/make/unit-tests/varname-dot-make-level.mk:1.6 --- src/usr.bin/make/unit-tests/varname-dot-make-level.mk:1.5 Sat Nov 23 22:59:51 2024 +++ src/usr.bin/make/unit-tests/varname-dot-make-level.mk Sat Mar 22 12:23:00 2025 @@ -1,29 +1,55 @@ -# $NetBSD: varname-dot-make-level.mk,v 1.5 2024/11/23 22:59:51 rillig Exp $ +# $NetBSD: varname-dot-make-level.mk,v 1.6 2025/03/22 12:23:00 rillig Exp $ # # Tests for the special .MAKE.LEVEL variable, which informs about the # recursion level. It is related to the environment variable MAKELEVEL, # even though they don't have the same value. -all: level_1 set-env +all: .PHONY level_1 set-env-same set-env-different +# expect: level 1: variable 0, env 1 level_1: .PHONY @printf 'level 1: variable %s, env %s\n' ${.MAKE.LEVEL} "$$${.MAKE.LEVEL.ENV}" @${MAKE} -f ${MAKEFILE} level_2 +# expect: level 2: variable 1, env 2 level_2: .PHONY @printf 'level 2: variable %s, env %s\n' ${.MAKE.LEVEL} "$$${.MAKE.LEVEL.ENV}" @${MAKE} -f ${MAKEFILE} level_3 -level_3: .PHONY - @printf 'level 3: variable %s, env %s\n' ${.MAKE.LEVEL} "$$${.MAKE.LEVEL.ENV}" - # The .unexport-env directive clears the environment, except for the -# MAKE_LEVEL variable. +# .MAKE.LEVEL.ENV make variable, which by default refers to the MAKELEVEL +# environment variable. .if make(level_2) .unexport-env .endif +# expect: level 3: variable 2, env 3 +level_3: .PHONY + @printf 'level 3: variable %s, env %s\n' ${.MAKE.LEVEL} "$$${.MAKE.LEVEL.ENV}" + + +# When a variable assignment from the command line tries to override a +# read-only global variable with the same value as before, ignore the +# assignment, as the variable value would not change. +# +# This special case allows older versions of make to coexist with newer +# versions of make. Older version of make (up to NetBSD 9) stored the internal +# .MAKE.LEVEL.ENV variable in the scope for command line variables, and these +# variables were passed to sub-makes via .MAKEOVERRIDES and the MAKEFLAGS +# environment variable. Newer versions of make (since NetBSD 11) store the +# internal .MAKE.LEVEL.ENV variable in the global scope but make it read-only +# and prevent any attempts to override it. +# +# https://gnats.netbsd.org/59184 +set-env-same: .PHONY + : ${.TARGET} + @${MAKE} -f ${MAKEFILE} ok .MAKE.LEVEL.ENV=${.MAKE.LEVEL.ENV} || echo "${.TARGET}: exit $$?" + # expect: make: Cannot override read-only global variable ".MAKE.LEVEL.ENV" with a command line variable -set-env: - @${MAKE} -f /dev/null .MAKE.LEVEL.ENV=MAKELEVEL +set-env-different: .PHONY + : ${.TARGET} + @${MAKE} -f ${MAKEFILE} ok .MAKE.LEVEL.ENV=CUSTOM || echo "${.TARGET}: exit $$?" + +ok: .PHONY + @echo ok