From: Stefano Lattarini Date: Tue, 15 May 2012 10:36:37 +0000 (+0200) Subject: [ng] memoize: correctly work around a bug of GNU make < 3.83 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=62f2e2d5860aa44d9a70eaef70b130580a3f62a0;p=thirdparty%2Fautomake.git [ng] memoize: correctly work around a bug of GNU make < 3.83 This is a follow-up to commit v1.12-218-g34a7d42 of 2012-05-15, "[ng] memoize: expose a serious bug (affecting GNU make < 3.83)". We implement a new workaround aimed at avoiding the subtle GNU make bug affecting variable memoization: Since that bug basically prevents dynamically reassigning to a variable inside the expansion of the variable itself, we reimplement memoization by having the memoized variable expanding to an $(if) branching either to evaluate-and-store in *another* memo variable, else to the value of that memo variable. The new workaround works also in the situation that was causing our previous workaround (as implemented in commit v1.12-217-gd55204f of 2012-05-12, "[ng] vars: implement memoization of make variables (new 'am__memoize' func)") to fail. Approach suggested by Akim Demaille: and coded by Stefano Lattarini. * lib/am/header-vars (am__memoize): Change API and implementation. (am__memoize_0): Delete, it's not needed anymore. * t/memoize.tap: Update to new API, also removing checks that makes no more sense with it. * t/spy-override.sh: Delete, it's not needed anymore. Co-authored-by: Akim Demaille Signed-off-by: Stefano Lattarini --- diff --git a/lib/am/header-vars.am b/lib/am/header-vars.am index 95345e438..d620c8948 100644 --- a/lib/am/header-vars.am +++ b/lib/am/header-vars.am @@ -83,19 +83,20 @@ am__uniq = $(strip \ ## we can't afford to re-calculate it over and over every time the ## variable gets expanded. Example of usage: ## -## memo/var1 = $(shell EXPENSIVE-COMMAND-LINE) -## memo/var2 = $(sort VERY-LONG-LIST) -## $(call am__memoize, var1 var2) +## var1 = $(am__memoize,var1,$(shell EXPENSIVE-COMMAND-LINE)) +## var2 = $(am__memoize,var2,$(sort VERY-LONG-LIST)) ## ## This API and implementation seems to work around a bug in GNU make ## (present up to and including version 3.82) which caused our first ## implementation attempts to fail: +## ## ## +## ## So please don't change this without a very good reason. -am__memoize_0 = $(eval $1 = $$(eval override $1 := $$$$($2))$$($1)) -am__memoize = $(foreach am__memo_var, $1, \ - $(call $(0)_0,$(am__memo_var),memo/$(am__memo_var))) +## +am__memoize = $(or $(am__memoized_value/$1),$(strip \ + $(eval am__memoized_value/$1 := $$2))$(am__memoized_value/$1)) ## Some derived variables that have been found to be useful. pkgdatadir = $(datadir)/@PACKAGE@ diff --git a/t/memoize.tap b/t/memoize.tap index f379e3426..ca7fedec6 100755 --- a/t/memoize.tap +++ b/t/memoize.tap @@ -19,7 +19,7 @@ am_create_testdir=empty . ./defs || Exit 1 -plan_ 14 +plan_ 13 ocwd=`pwd` || fatal_ "couldn't get current working directory" @@ -52,8 +52,7 @@ tcount=0 T "basic usage" <<'END' -memo/foo = ok -$(call am__memoize,foo) +foo = $(call am__memoize,foo,ok) test: test '$(foo)' = ok @@ -62,28 +61,25 @@ END #--------------------------------------------------------------------------- -T "call with extra spaces" <<'END' +T "variables expanding to blanks only (1)" <<'END' -memo/foo = ok -## There are extra spaces and tabs here; do not normalize them! -$(call am__memoize, foo ) +foo = $(call am__memoize,foo,$(am__empty) ) test: - test '$(foo)' = ok - test '$(foo)' = ok + test '$(foo)' = ' ' + test '$(foo)' = ' ' END #--------------------------------------------------------------------------- -T "memoize several variables at once" <<'END' +T "variables expanding to blanks only (2)" < t/pm/Cond2.pl) TESTS = $(wildcard t/pm/Cond2.pl) -memo/am__test_bases = $(TESTS) -$(call am__memoize,am__test_bases) +am__test_bases = $(call am__memoize,am__test_bases,$(TESTS)) test: test '$(am__test_bases)' = 't/pm/Cond2.pl' @@ -276,10 +250,11 @@ for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20; do mv -f t1 t done -(echo 'memo/list = \' && cat t && echo " $line") > big.mk +echo "list = \$(call am__memoize,list,$line \\" >> big.mk +cat t >> big.mk +echo " $line)" >> big.mk cat >> big.mk << 'END' -$(call am__memoize,list) test: test x'$(word 1, $(list))' = x'dummy' test x'$(word 3, $(list))' = x'=' diff --git a/t/spy-override.sh b/t/spy-override.sh deleted file mode 100755 index de552e496..000000000 --- a/t/spy-override.sh +++ /dev/null @@ -1,51 +0,0 @@ -#! /bin/sh -# Copyright (C) 2012 Free Software Foundation, Inc. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License as published by -# the Free Software Foundation; either version 2, or (at your option) -# any later version. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . - -# Verify that use of 'override' directive to re-set a variable does -# not cause any warning or extra output. - -am_create_testdir=empty -. ./defs || Exit 1 - -cat > Makefile <<'END' -foo = 1 -override foo = 2 - -bar = 3 -override bar := 4 - -override baz = 6 -override zap := 8 - -override zardoz += doz - -nihil: - @: -sanity-check: - test '$(foo)' = 2 - test '$(bar)' = 4 - test '$(baz)' = 6 - test '$(zap)' = 8 - test '$(zardoz)' = 'zar doz' -.PHONY: nihil sanity-check -END - -$MAKE sanity-check baz=5 zap=7 zardoz=zar -$MAKE --no-print-directory nihil >output 2>&1 \ - && test ! -s output \ - || { cat output; Exit 1; } - -: