# -*-perl-*- $description = "Test target-specific variable settings."; $details = "\ Create a makefile containing various flavors of target-specific variable values, override and non-override, and using various variable expansion rules, semicolon interference, etc."; run_make_test(' export FOO = foo export BAR = bar one: override FOO = one one two: ; @echo $(FOO) $(BAR) two: BAR = two .RECIPEPREFIX = > three: ; BAR=1000 > @echo $(FOO) $(BAR) # Some things that shouldn not be target vars funk : override funk : override adelic adelic override : ; echo $@ # Test per-target recursive variables four:FOO=x four:VAR$(FOO)=ok four: ; @echo "$(FOO) $(VAR$(FOO)) $(VAR) $(VARx)" five:FOO=x five six : VAR$(FOO)=good five six: ;@echo "$(FOO) $(VAR$(FOO)) $(VAR) $(VARx) $(VARfoo)" # Test per-target variable inheritance seven: eight seven eight: ; @echo $@: $(FOO) $(BAR) seven: BAR = seven seven: FOO = seven eight: BAR = eight # Test the export keyword with per-target variables nine: ; @echo $(FOO) $(BAR) $$FOO $$BAR nine: FOO = wallace nine-a: export BAZ = baz nine-a: ; @echo $$BAZ # Test = escaping EQ = = ten: one$(EQ)two ten: one $(EQ) two ten one$(EQ)two $(EQ):;@echo $@ .PHONY: one two three four five six seven eight nine ten $(EQ) one$(EQ)two # Test target-specific vars with pattern/suffix rules QVAR = qvar RVAR = = %.q : ; @echo $(QVAR) $(RVAR) foo.q : RVAR += rvar # Target-specific vars with multiple LHS pattern rules %.r %.s %.t: ; @echo $(QVAR) $(RVAR) $(SVAR) $(TVAR) foo.r : RVAR += rvar foo.t : TVAR := $(QVAR) ', "one two three", "one bar\nfoo two\nBAR=1000\nfoo bar\n"); # TEST #2 run_make_test(undef, "one two FOO=1 BAR=2", "one 2\n1 2\n"); # TEST #3 run_make_test(undef, "four", "x ok ok\n"); # TEST #4 run_make_test(undef, "seven", "eight: seven eight\nseven: seven seven\n"); # TEST #5 run_make_test(undef, "nine", "wallace bar wallace bar\n"); # TEST #5-a run_make_test(undef, "nine-a", "baz\n"); # TEST #6 run_make_test(undef, "ten", "one=two\none bar\n=\nfoo two\nten\n"); # TEST #6 run_make_test(undef, "foo.q bar.q", "qvar = rvar\nqvar =\n"); # TEST #7 run_make_test(undef, "foo.t bar.s", "qvar = qvar\nqvar =\n"); # TEST #8 # For PR/1378: Target-specific vars don't inherit correctly run_make_test(' foo: FOO = foo bar: BAR = bar foo: bar bar: baz baz: ; @echo $(FOO) $(BAR) ', "", "foo bar\n"); # TEST #9 # For PR/1380: Using += assignment in target-specific variables sometimes fails # Also PR/1831 run_make_test(' .PHONY: all one all: FOO += baz all: one; @echo $(FOO) FOO = bar one: FOO += biz one: FOO += boz one: ; @echo $(FOO) ', '', "bar baz biz boz\nbar baz\n"); # Test #10 run_make_test(undef, 'one', "bar biz boz\n"); # Test #11 # PR/1709: Test semicolons in target-specific variable values run_make_test(' foo : FOO = ; ok foo : ; @echo "$(FOO)" ', '', "; ok\n"); # Test #12 # PR/2020: More hassles with += target-specific vars. I _really_ think # I nailed it this time :-/. run_make_test(' .PHONY: a BLAH := foo COMMAND = echo $(BLAH) a: ; @$(COMMAND) a: BLAH := bar a: COMMAND += snafu $(BLAH) ', '', "bar snafu bar\n"); # Test #13 # Test double-colon rules with target-specific variable values run_make_test(' W = bad X = bad foo: W = ok foo:: ; @echo $(W) $(X) $(Y) $(Z) foo:: ; @echo $(W) $(X) $(Y) $(Z) foo: X = ok Y = foo bar: foo bar: Y = bar Z = nopat ifdef PATTERN fo% : Z = pat endif ', 'foo', "ok ok foo nopat\nok ok foo nopat\n"); # Test #14 # Test double-colon rules with target-specific variable values and # inheritance run_make_test(undef, 'bar', "ok ok bar nopat\nok ok bar nopat\n"); # Test #15 # Test double-colon rules with pattern-specific variable values run_make_test(undef, 'foo PATTERN=yes', "ok ok foo pat\nok ok foo pat\n"); # Test #16 # Test target-specific variables with very long command line # (> make default buffer length) run_make_test(' base_metals_fmd_reports.sun5 base_metals_fmd_reports CreateRealPositions CreateMarginFunds deals_changed_since : BUILD_OBJ=$(shell if test -f "build_information.generate" ; then echo "$(OBJ_DIR)/build_information.o"; else echo "no build information"; fi ) deals_changed_since: ; @echo $(BUILD_OBJ) ', '', "no build information\n"); # TEST #17 # Test a merge of set_lists for files, where one list is much longer # than the other. See Savannah bug #15757. mkdir('t1', 0777); touch('t1/rules.mk'); run_make_test(' VPATH = t1 include rules.mk .PHONY: all all: foo.x foo.x : rules.mk ; @echo MYVAR=$(MYVAR) FOOVAR=$(FOOVAR) ALLVAR=$(ALLVAR) all: ALLVAR = xxx foo.x: FOOVAR = bar rules.mk : MYVAR = foo .INTERMEDIATE: foo.x rules.mk ', '-I t1', 'MYVAR= FOOVAR=bar ALLVAR=xxx'); rmfiles('t1/rules.mk'); rmdir('t1'); # TEST #18 # Test appending to a simple variable containing a "$": avoid a # double-expansion. See Savannah bug #15913. run_make_test(' VAR := $$FOO foo: VAR += BAR foo: ; @echo '."'".'$(VAR)'."'".' ', '', '$FOO BAR'); # TEST #19: Override with append variables run_make_test(' a: override FOO += f1 a: FOO += f2 a: ; @echo "$(FOO)" ', '', "f1\n"); run_make_test(undef, 'FOO=C', "C f1\n"); # TEST #19: Conditional variables with command-line settings run_make_test(' a: FOO ?= f1 a: ; @echo "$(FOO)" ', '', "f1\n"); run_make_test(undef, 'FOO=C', "C\n"); # TEST #20: Check for continuation after semicolons run_make_test(q! a: A = 'hello;\ world' a: ; @echo $(A) !, '', "hello; world\n"); # TEST #21: SV-56834 Ensure setting PATH in a target var works properly my $sname = "foobar$scriptsuffix"; mkdir('sd', 0775); create_file("sd/$sname", "exit 0\n"); chmod 0755, "sd/$sname"; run_make_test(qq! all: PATH := sd all: ; $sname >/dev/null !, '', "$sname >/dev/null\n"); # Don't use the general PATH if not found on the target path $ENV{PATH} = "$ENV{PATH}:sd"; my ($ernum, $erstr); if ($port_type eq 'W32') { $ernum = 1; $erstr = "'$sname' is not recognized as an internal or external command,\noperable program or batch file."; } else { $ernum = 127; $erstr = "#MAKE#: $sname: $ERR_no_such_file"; } run_make_test(qq! all: PATH := .. all: ; $sname !, '', "$sname\n$erstr\n#MAKE#: *** [#MAKEFILE#:3: all] Error $ernum", 512); unlink("sd/$sname"); rmdir ('sd'); # SV 59230: Conditional (non-)assignment of target-specific variables should # preserve export settings. $ENV{hello} = 'moon'; run_make_test(q! all:; @echo hello=$$hello dummy: hello?=world !, '', 'hello=moon'); # SV 59230: Assignment of a global variable should not affect export of a # target specific variable. $ENV{hello} = "moon"; run_make_test(q! all:; @echo hello=$$hello hello=sun dummy: hello?=world !, '', 'hello=sun'); # Support target-specific unexport $ENV{hello} = "moon"; run_make_test(q! unexport hello=sun all: base exp base exp: ; @echo hello=$$hello exp: export hello=world !, '', "hello=\nhello=world\n"); $ENV{hello} = "moon"; run_make_test(q! hello=sun all: base exp base exp: ; @echo hello=$$hello exp: unexport hello=world !, '', "hello=sun\nhello=\n"); run_make_test(q! all:; @echo hello=$$hello unexport hello=sun dummy: hello?=world !, '', 'hello='); $ENV{hello} = "moon"; run_make_test(q! all:; @echo hello=$$hello hello=sun dummy: unexport hello=world !, '', 'hello=sun'); run_make_test(q! all: mid mid: base ifeq ($(midexport),export) mid: export hello=mid else ifeq ($(midexport),unexport) mid: unexport hello=mid else mid: hello=mid endif ifeq ($(baseexport),export) base: export hello=base else ifeq ($(baseexport),unexport) base: unexport hello=base else base: hello=base endif all mid base:; @echo $@ make=$(hello) shell=$$hello !, '', "base make=base shell=\nmid make=mid shell=\nall make= shell=\n"); # Test base settings with env var $ENV{hello} = "environ"; run_make_test(undef, '', "base make=base shell=base\nmid make=mid shell=mid\nall make=environ shell=environ\n"); $ENV{hello} = "environ"; run_make_test(undef, 'baseexport=export', "base make=base shell=base\nmid make=mid shell=mid\nall make=environ shell=environ\n"); $ENV{hello} = "environ"; run_make_test(undef, 'baseexport=unexport', "base make=base shell=\nmid make=mid shell=mid\nall make=environ shell=environ\n"); # Test mid settings with env var $ENV{hello} = "environ"; run_make_test(undef, 'midexport=export', "base make=base shell=base\nmid make=mid shell=mid\nall make=environ shell=environ\n"); $ENV{hello} = "environ"; run_make_test(undef, 'midexport=export baseexport=unexport', "base make=base shell=\nmid make=mid shell=mid\nall make=environ shell=environ\n"); $ENV{hello} = "environ"; run_make_test(undef, 'midexport=unexport', "base make=base shell=\nmid make=mid shell=\nall make=environ shell=environ\n"); $ENV{hello} = "environ"; run_make_test(undef, 'midexport=unexport baseexport=export', "base make=base shell=base\nmid make=mid shell=\nall make=environ shell=environ\n"); # Test base settings without env var run_make_test(undef, 'baseexport=export', "base make=base shell=base\nmid make=mid shell=\nall make= shell=\n"); run_make_test(undef, 'baseexport=unexport', "base make=base shell=\nmid make=mid shell=\nall make= shell=\n"); # Test mid settings with env var run_make_test(undef, 'midexport=export', "base make=base shell=base\nmid make=mid shell=mid\nall make= shell=\n"); run_make_test(undef, 'midexport=export baseexport=unexport', "base make=base shell=\nmid make=mid shell=mid\nall make= shell=\n"); run_make_test(undef, 'midexport=unexport', "base make=base shell=\nmid make=mid shell=\nall make= shell=\n"); run_make_test(undef, 'midexport=unexport baseexport=export', "base make=base shell=base\nmid make=mid shell=\nall make= shell=\n"); # TEST #19: Test define/endef variables as target-specific vars # run_make_test(' # define b # @echo global # endef # a: define b # @echo local # endef # a: ; $(b) # ', # '', "local\n"); 1;