make/tests/scripts/features/se_implicit
Dmitry Goncharov 8c2aa889bb [SV 62324] Simplify set_file_variables by passing in the stem
Previously we always used the file->stem value as our stem in
set_file_variables(); when that wasn't correct we had to temporarily
set that value while the function was called, then reset it afterward.
This led to issues (for example when we assumed the stem was a cached
string but it wasn't).

Avoid this by passing in the stem as an argument so that different
values can be provided.

Add tests to verify this.

* src/commands.c (set_file_variables): Take second parameter stem to
relieve the callers of set_file_variables() from setting/restoring
file->stem.
* src/commands.h (set_file_variables): Ditto.
(execute_file_commands): Pass file->stem to set_file_variables().
* src/file.c (expand_deps): Pass d->stem to set_file_variables() and
remove set and restore of file->stem.
* src/implicit.c (pattern_search): Pass stem to set_file_variables()
and remove set and restore of file->stem.
* tests/scripts/features/se_explicit: Add new tests.
* tests/scripts/features/se_implicit: Ditto.
* tests/scripts/features/se_statpat: Ditto.
* tests/scripts/variables/automatic: Ditto.
2022-04-24 10:39:32 -04:00

446 lines
8.3 KiB
Perl

# -*-perl-*-
$description = "Test second expansion in implicit rules.";
$details = "";
use Cwd;
$dir = cwd;
$dir =~ s,.*/([^/]+)$,../$1,;
# Test #1: automatic variables.
#
run_make_test(q!
.SECONDEXPANSION:
.DEFAULT: ; @echo '$@'
foo.a: bar baz
foo.a: biz | buz
foo.%: 1.$$@ \
2.$$< \
$$(addprefix 3.,$$^) \
$$(addprefix 4.,$$+) \
5.$$| \
6.$$* ; @:
1.foo.a \
2.bar \
3.bar \
3.baz \
3.biz \
4.bar \
4.baz \
4.biz \
5.buz \
6.a: ; @echo '$@'
!,
'',
'1.foo.a
2.bar
3.bar
3.baz
3.biz
4.bar
4.baz
4.biz
5.buz
6.a
bar
baz
biz
buz
');
# Test #2: target/pattern -specific variables.
#
run_make_test(q!
.SECONDEXPANSION:
foo.x:
foo.%: $$(%_a) $$(%_b) bar ; @:
foo.x: x_a := bar
%.x: x_b := baz
bar baz: ; @echo '$@'
!,
'', "bar\nbaz\n");
# Test #3: order of prerequisites.
#
run_make_test(q!
.SECONDEXPANSION:
.DEFAULT: ; @echo '$@'
all: foo bar baz
# Subtest #1
#
%oo: %oo.1; @:
foo: foo.2
foo: foo.3
foo.1: ; @echo '$@'
# Subtest #2
#
bar: bar.2
%ar: %ar.1; @:
bar: bar.3
bar.1: ; @echo '$@'
# Subtest #3
#
baz: baz.1
baz: baz.2
%az: ; @:
!,
'',
'foo.1
foo.2
foo.3
bar.1
bar.2
bar.3
baz.1
baz.2
');
# Test #4: stem splitting logic.
#
run_make_test(q!
.SECONDEXPANSION:
$(dir)/tmp/bar.o:
$(dir)/tmp/foo/bar.c: ; @echo '$@'
$(dir)/tmp/bar/bar.c: ; @echo '$@'
foo.h: ; @echo '$@'
%.o: $$(addsuffix /%.c,foo bar) foo.h ; @echo '$@: {$<} $^'
!,
"dir=$dir", "$dir/tmp/foo/bar.c
$dir/tmp/bar/bar.c
foo.h
$dir/tmp/bar.o: {$dir/tmp/foo/bar.c} $dir/tmp/foo/bar.c $dir/tmp/bar/bar.c foo.h
");
# Test #5: stem splitting logic and order-only prerequisites.
#
run_make_test(q!
.SECONDEXPANSION:
$(dir)/tmp/foo.o: $(dir)/tmp/foo.c
$(dir)/tmp/foo.c: ; @echo '$@'
bar.h: ; @echo '$@'
%.o: %.c|bar.h ; @echo '$@: {$<} {$|} $^'
!,
"dir=$dir", "$dir/tmp/foo.c
bar.h
$dir/tmp/foo.o: {$dir/tmp/foo.c} {bar.h} $dir/tmp/foo.c
");
# Test #6: lack of implicit prerequisites.
#
run_make_test(q!
.SECONDEXPANSION:
foo.o: foo.c
foo.c: ; @echo '$@'
%.o: ; @echo '$@: {$<} $^'
!,
'', "foo.c\nfoo.o: {foo.c} foo.c\n");
# Test #7: Test stem from the middle of the name.
#
run_make_test(q!
.SECONDEXPANSION:
foobarbaz:
foo%baz: % $$*.1 ; @echo '$*'
bar bar.1: ; @echo '$@'
!,
'', "bar\nbar.1\nbar\n");
# Test #8: Make sure stem triple-expansion does not happen.
#
run_make_test(q!
.SECONDEXPANSION:
foo$$bar:
f%r: % $$*.1 ; @echo '$*'
oo$$ba oo$$ba.1: ; @echo '$@'
!,
'', 'oo$ba
oo$ba.1
oo$ba
');
# Test #9: Check the value of $^
run_make_test(q!
.SECONDEXPANSION:
%.so: | $$(extra) ; @echo $^
foo.so: extra := foo.o
foo.so:
foo.o:
!,
'', "\n");
# Test #10: Test second expansion with second expansion prerequisites
# Ensures pattern_search() recurses with SE prereqs.
touch('a');
run_make_test(q!
.SECONDEXPANSION:
sim_base_rgg := just_a_name
sim_base_src := a
sim_base_f := a a a
sim_%.f: $${sim_$$*_f} ; echo $@
sim_%.src: $${sim_$$*_src} ; echo $@
sim_%: \
$$(if $$(sim_$$*_src),sim_%.src) \
$$(if $$(sim_$$*_f),sim_%.f) \
$$(if $$(sim_$$*_rgg),$$(sim_$$*_rgg).s) ; echo $@
!,
'-s sim_base', "#MAKE#: *** No rule to make target 'sim_base'. Stop.", 512);
unlink('a');
# Ensure that order-only tokens embedded in second expansions are parsed
run_make_test(q!
.SECONDEXPANSION:
PREREQS=p1|p2
P2=p2
all : foo bar
f%o: $$(PREREQS) ; @echo '$@' from '$^' and '$|'
b%r: p1|$$(P2) ; @echo '$@' from '$^' and '$|'
p% : ; : $@
!,
"", ": p1\n: p2\nfoo from p1 and p2\nbar from p1 and p2\n");
# SV 28456 : Don't reset $$< for default recipes
run_make_test(q!
.SECONDEXPANSION:
.PHONY: foo bar
foo: bar
foo: $$(info $$<)
%oo: ;
!,
'', "bar\n#MAKE#: Nothing to be done for 'foo'.\n");
# SV 54161: Expand $$* properly when it contains a path
run_make_test(q!
.SECONDEXPANSION:
%x: $$(info $$*); @echo '$*'
!,
'q/ux', "q/u\nq/u\n");
# sv 60188.
# Test that a file explicitly mentioned by the user and made by an implicit
# rule is not considered intermediate.
touch('hello.z');
# subtest 1.
# hello.x is derived from the stem and thus is an intermediate file.
run_make_test(q!
.SECONDEXPANSION:
dep:=.x
all: hello.z
%.z: %$$(dep) ; @echo $@
%.x: ;
!, '', "#MAKE#: Nothing to be done for 'all'.\n");
# subtest 2.
# test.x is explicitly mentioned and thus is not an intermediate file.
run_make_test(q!
.SECONDEXPANSION:
dep:=test.x
all: hello.z
%.z: %.x $$(dep) ; @echo $@
%.x: ;
!, '', "hello.z\n");
# subtest 3.
# hello.x is explicitly mentioned on an unrelated rule and thus is not an
# intermediate file.
run_make_test(q!
.SECONDEXPANSION:
dep:=hello.x
all: hello.z
%.z: %.x; @echo $@
%.x: ;
unrelated: $$(dep)
!, '', "hello.z\n");
unlink('hello.z');
# sv 60188.
# Test that a file explicitly mentioned by the user and made by an implicit
# rule is not considered intermediate, even when the builtin rules are used.
touch('hello.x');
touch('hello.tsk');
# subtest 1.
# hello.z is explicitly mentioned and thus is not an intermediate file.
run_make_test(q!
.SECONDEXPANSION:
dep:=hello.z
all: hello.tsk
%.tsk: $$(dep) ; @echo $@
%.z : %.x ; @echo $@
!, '', "hello.z\nhello.tsk");
# subtest 2.
# hello.z is derived from the stem and thus is an intermediate file.
run_make_test(q!
.SECONDEXPANSION:
dep:=.z
all: hello.tsk
%.tsk: %$$(dep) ; @echo $@
%.z : %.x ; @echo $@
!, '', "#MAKE#: Nothing to be done for 'all'.\n");
unlink('hello.x');
unlink('hello.tsk');
# sv 60659. Second expansion of automatic variables inside a function in the
# prerequisite list.
# $$@ expands to the target in the 1st and following rules.
# $$* expands to the stem in the 1st and following rules.
# $$<,$$^,$$+,$$|,$$?,$$% expand to the empty string in the prerequisite list
# of the 1st rule.
# $$<,$$^,$$+,$$|,$$?,$$% in the prerequisite list of the 2nd (and following)
# rule expand to the values from the 1st rule.
# $$% cannot be used in prerequisites, because in pattern rules % is
# substituted for stem.
# subtest 1. Pattern rules. 1st rule.
run_make_test(q!
.SECONDEXPANSION:
all: 2.x
%.x: 5.z 6.z 5.z $$(info @=$$@,<=$$<,^=$$^,+=$$+,|=$$|,?=$$?,*=$$*) ;
%.z: ;
!, '',
"@=2.x,<=,^=,+=,|=,?=,*=2
#MAKE#: Nothing to be done for 'all'.\n");
# subtest 2. Pattern rules. 2nd rule.
run_make_test(q!
.SECONDEXPANSION:
all: 2.x 1.x
2.x: 5.z 6.z 5.z | 7.z 7.z 8.z
1.x: 1.z 2.z 2.z | 3.z 4.z
%.x: 9.z $$(info @=$$@,<=$$<,^=$$^,+=$$+,|=$$|,?=$$?,*=$$*) ;
%.z: ;
!, '',
"@=2.x,<=5.z,^=5.z 6.z,+=5.z 6.z 5.z,|=7.z 8.z,?=,*=2
@=1.x,<=1.z,^=1.z 2.z,+=1.z 2.z 2.z,|=3.z 4.z,?=,*=1
#MAKE#: Nothing to be done for 'all'.\n");
# subtest 3. Static pattern rules. 1st rule.
run_make_test(q!
.SECONDEXPANSION:
all: 2.x
2.x: %.x: 5.z 6.z 5.z $$(info @=$$@,<=$$<,^=$$^,+=$$+,|=$$|,?=$$?,*=$$*) ;
%.z: ;
!, '',
"@=2.x,<=,^=,+=,|=,?=,*=2
#MAKE#: Nothing to be done for 'all'.\n");
# subtest 4. Static pattern rules. 2nd rule.
run_make_test(q!
.SECONDEXPANSION:
all: 2.x 1.x
2.x: 5.z 6.z 5.z | 7.z 7.z 8.z
1.x: 1.z 2.z 2.z | 3.z 4.z
2.x 1.x: %.x: 9.z $$(info @=$$@,<=$$<,^=$$^,+=$$+,|=$$|,?=$$?,*=$$*) ;
%.z: ;
!, '',
"@=2.x,<=5.z,^=5.z 6.z,+=5.z 6.z 5.z,|=7.z 8.z,?=,*=2
@=1.x,<=1.z,^=1.z 2.z,+=1.z 2.z 2.z,|=3.z 4.z,?=,*=1
#MAKE#: Nothing to be done for 'all'.\n");
# subtest 5. Grouped targets in implicit rules. 1st rule.
run_make_test(q!
.SECONDEXPANSION:
all: 2.x
%.x %.xx&: 5.z 6.z 5.z $$(info @=$$@,<=$$<,^=$$^,+=$$+,|=$$|,?=$$?,*=$$*) ;
%.z: ;
!, '',
"@=2.x,<=,^=,+=,|=,?=,*=2
#MAKE#: Nothing to be done for 'all'.\n");
# subtest 6. Grouped targets in implicit rules. 2nd rule.
run_make_test(q!
.SECONDEXPANSION:
all: 2.x 1.xx
2.x: 5.z 6.z 5.z | 7.z 7.z 8.z
1.xx: 1.z 2.z 2.z | 3.z 4.z
%.x %.xx&: 9.z $$(info @=$$@,<=$$<,^=$$^,+=$$+,|=$$|,?=$$?,*=$$*) ;
%.z: ;
!, '',
"@=2.x,<=5.z,^=5.z 6.z,+=5.z 6.z 5.z,|=7.z 8.z,?=,*=2
@=1.xx,<=1.z,^=1.z 2.z,+=1.z 2.z 2.z,|=3.z 4.z,?=,*=1
#MAKE#: Nothing to be done for 'all'.\n");
# subtest 7. Double colon rule.
run_make_test(q!
.SECONDEXPANSION:
all: 2.x
%.x:: 5.z 6.z 5.z $$(info @=$$@,<=$$<,^=$$^,+=$$+,|=$$|,?=$$?,*=$$*) ;
5.z 6.z: ;
!, '',
"@=2.x,<=,^=,+=,|=,?=,*=2
#MAKE#: Nothing to be done for 'all'.\n");
# sv 62324.
# Integrity self check.
run_make_test(q!
.SECONDEXPANSION:
all: bye.x
%.x: $$(firstword %.1;
!, '', "#MAKE#: *** unterminated call to function 'firstword': missing ')'. Stop.", 512);
# This tells the test driver that the perl test script executed properly.
1;