From e2004fd5ed8420617af1d31b99228908b0a3b948 Mon Sep 17 00:00:00 2001 From: Stefano Lattarini Date: Fri, 27 Jul 2012 20:30:11 +0200 Subject: [PATCH] [ng] utils: new function 'am.vars.is-undef' Sometimes, in our makefiles, we want to assign a default value to a variable that might not have been assigned yet. One might think that using the GNU make assignment '?=' is enough: VAR ?= DEFAULT-VALUE But alas, such a usage allows interferences from the environment; i.e., if an environment variable named 'VAR' is defined to, say, BAD-VALUE, the construct above will result in the $(VAR) make variable being defined to BAD-VALUE, not to DEFAULT-VALUE. Use the 'am.vars.is-undef' function to avoid this situation. It tells whether the given make variable is not "safely" defined, i.e., either undefined, or defined to a value that is inherited from the environment. With such a tool, we can safely declare default values for variables that avoids environmental interferences, as follow: ifeq ($(call am.vars.is-undef,VAR),yes) VAR = DEFAULT-VALUE endif * lib/am/header-vars.am (am.vars.is-undef): New. * t/internals.tap: Test it, and add few sanity checks. Signed-off-by: Stefano Lattarini --- lib/am/header-vars.am | 27 +++++++++++++++++++++ t/internals.tap | 56 +++++++++++++++++++++++++++++++++++++++++-- 2 files changed, 81 insertions(+), 2 deletions(-) diff --git a/lib/am/header-vars.am b/lib/am/header-vars.am index 472d0b2b5..6bbde638a 100644 --- a/lib/am/header-vars.am +++ b/lib/am/header-vars.am @@ -45,6 +45,33 @@ define am.error $(warning $1)$(eval am.error.seen := yes) endef +# +# Sometimes, in our makefiles, we want to assign a default value to a +# variable that might not have been assigned yet. One might think that +# using the GNU make assignment '?=' is enough: +# +# VAR ?= DEFAULT-VALUE +# +# But alas, such a usage allows interferences from the environment; i.e., +# if an environment variable named 'VAR' is defined to, say, BAD-VALUE, +# the construct above will result in the $(VAR) make variable being +# defined to BAD-VALUE, not to DEFAULT-VALUE. +# +# Use the 'am.vars.is-undef' function to avoid this situation. It tells +# whether the given make variable is not "safely" defined, i.e., either +# undefined, or defined to a value that is inherited from the environment. +# +# With such a tool, we can safely declare default values for variables +# that avoids environmental interferences, as follow: +# +# ifeq ($(call am.vars.is-undef,VAR),yes) +# VAR = DEFAULT-VALUE +# endif +# +define am.vars.is-undef +$(if $(filter undefined environment,$(origin $(strip $1))),yes) +endef + # Some problematic characters (especially when used in arguments # to make functions, or for syntax highlighting). am.chars.bslash := \\ diff --git a/t/internals.tap b/t/internals.tap index ac53396a5..91449a0db 100755 --- a/t/internals.tap +++ b/t/internals.tap @@ -19,7 +19,7 @@ am_create_testdir=empty . ./defs || exit 1 -plan_ 10 +plan_ 12 # Filter out Automake comments. grep -v '^##' "$am_amdir"/header-vars.am > defn.mk \ @@ -42,10 +42,18 @@ T () echo 'digits = 0123456789' } > Makefile cat >> Makefile - command_ok_ "$*" $MAKE test + test_name=$1; shift + command_ok_ "$test_name" $MAKE ${1+"$@"} test cd .. } +T 'sanity check' FOO=ok <<'END' +FOO = ko +test: + test $(FOO) = ok + touch sane +END +test -f T1.d/sane || fatal_ "function 'T' is buggy" T 'am.util.strip-first-word' <<'END' test: @@ -174,6 +182,50 @@ test: test '$(call am.util.canon,x$(comma)@$(bslash))' = 'x_@_' END +FOO_ENVIRON=ok; export FOO_ENVIRON +FOO_UNDEF=; unset FOO_UNDEF +FOO_INDIR=; unset FOO_INDIR +T 'am.vars.is-undef' FOO_CMDLINE=ok <<'END' + +FOO_MAKEFILE_1 = ok +FOO_MAKEFILE_2 := ok +override FOO_OVERRIDE_1 = ok +override FOO_OVERRIDE_2 := ok +FOO_EMPTY_1 = +FOO_EMPTY_2 := + +# Help avoiding typos. +X = $(call am.vars.is-undef,$1) + +test: + @echo UNDEF: + test '$(call X,FOO_UNDEF)' = yes + @echo ENVIRON: + test '$(call X,FOO_ENVIRON)' = yes + @echo MAKEFILE 1: + test -z '$(call X,FOO_MAKEFILE_1)' + @echo MAKEFILE 2: + test -z '$(call X,FOO_MAKEFILE_2)' + @echo CMDLINE: + test -z '$(call X,FOO_CMDLINE)' + @echo OVERRIDE 1: + test -z '$(call X,FOO_OVERRIDE_1)' + @echo OVERRIDE 2: + test -z '$(call X,FOO_OVERRIDE_2)' + @echo EMPTY 1: + test -z '$(call X,FOO_EMPTY_1)' + @echo EMPTY 2: + test -z '$(call X,FOO_EMPTY_2)' + @echo DEFAULT: + test -z '$(call X,CC)' + @echo EXTRA SPACES: + test '$(call X, FOO_UNDEF )' = yes + @echo SANITY CHECKS: + test '$(FOO_ENVIRON)' = ok + test '$(FOO_CMDLINE)' = ok +END +unset FOO_ENVIRON + T 'am.chars.newline (1)' <<'END' test: @echo OK > fo1$(am.chars.newline)@touch ba1$(am.chars.newline)-false > qu1 -- 2.47.2