mirror of
https://git.savannah.gnu.org/git/make.git
synced 2025-01-13 09:25:46 +00:00
8c2aa889bb
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.
446 lines
8.3 KiB
Perl
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;
|