[SV 60659] Set $$< properly in second expansion

Set the $$< automatic variable as best we can during secondary
expansion of prerequisites.

* src/commands.c (set_file_variables): Don't break without setting
'less' if secondary expansion is enabled.
* tests/scripts/features/se_explicit: Test secondary expansion results.
* tests/scripts/features/se_implicit: Test secondary expansion results.
This commit is contained in:
Dmitry Goncharov 2021-05-29 19:03:07 -04:00 committed by Paul Smith
parent f2771aa614
commit b580949ae0
3 changed files with 192 additions and 3 deletions

View file

@ -133,10 +133,9 @@ set_file_variables (struct file *file)
/* $< is the first not order-only dependency. */
less = "";
for (d = file->deps; d != 0; d = d->next)
if (!d->ignore_mtime && !d->ignore_automatic_vars)
if (!d->ignore_mtime && !d->ignore_automatic_vars && !d->need_2nd_expansion)
{
if (!d->need_2nd_expansion)
less = dep_name (d);
less = dep_name (d);
break;
}

View file

@ -200,4 +200,96 @@ biz: $$(info $$<)
!,
'', "baz\n#MAKE#: Nothing to be done for 'biz'.\n");
# sv 60659. Second expansion of automatic variables inside a function in the
# prerequisite list.
# $$@ expands to the target 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.
# subtest 1. Explicit rules. 1st rule.
run_make_test(q!
.SECONDEXPANSION:
all: 2.x
2.x: 5.z 6.z 5.z $$(info @=$$@,<=$$<,^=$$^,+=$$+,|=$$|,?=$$?,*=$$*,%=$$%) ;
%.z: ;
!, '',
"@=2.x,<=,^=,+=,|=,?=,*=,%=
#MAKE#: Nothing to be done for 'all'.\n");
# subtest 2. Explicit 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: 9.z $$(info @=$$@,<=$$<,^=$$^,+=$$+,|=$$|,?=$$?,*=$$*,%=$$%) ;
%.z: ;
!, '',
"@=2.x,<=5.z,^=5.z 6.z,+=5.z 6.z 5.z,|=7.z 8.z,?=,*=,%=
@=1.x,<=1.z,^=1.z 2.z,+=1.z 2.z 2.z,|=3.z 4.z,?=,*=,%=
#MAKE#: Nothing to be done for 'all'.\n");
# subtest 3. Grouped targets in explicit rules. 1st rule.
run_make_test(q!
.SECONDEXPANSION:
all: 2.x
2.x 1.x&: 5.z 6.z 5.z $$(info @=$$@,<=$$<,^=$$^,+=$$+,|=$$|,?=$$?,*=$$*,%=$$%) ;
%.z: ;
!, '',
"@=2.x,<=,^=,+=,|=,?=,*=,%=
@=1.x,<=,^=,+=,|=,?=,*=,%=
#MAKE#: Nothing to be done for 'all'.\n");
# subtest 4. Grouped targets in explicit 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&: 9.z $$(info @=$$@,<=$$<,^=$$^,+=$$+,|=$$|,?=$$?,*=$$*,%=$$%) ;
%.z: ;
!, '',
"@=2.x,<=5.z,^=5.z 6.z,+=5.z 6.z 5.z,|=7.z 8.z,?=,*=,%=
@=1.x,<=1.z,^=1.z 2.z,+=1.z 2.z 2.z,|=3.z 4.z,?=,*=,%=
#MAKE#: Nothing to be done for 'all'.\n");
# Double colon rules.
# Because each double colon rule is independent of the other double colon rules
# for the same target, each automatic variable in the prerequisite list, other
# than $$@, second expands to the empty string in any rule, 1st, 2nd or later.
# subtest 5. 1st double colon rule.
run_make_test(q!
.SECONDEXPANSION:
all: 2.x
2.x:: 5.z 6.z 5.z $$(info @=$$@,<=$$<,^=$$^,+=$$+,|=$$|,?=$$?,*=$$*,%=$$%) ;
%.z: ;
!, '',
"@=2.x,<=,^=,+=,|=,?=,*=,%=
#MAKE#: Nothing to be done for 'all'.\n");
# subtest 6. 2nd double colon 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:: 9.z $$(info @=$$@,<=$$<,^=$$^,+=$$+,|=$$|,?=$$?,*=$$*,%=$$%) ;
%.z: ;
!, '',
"@=2.x,<=,^=,+=,|=,?=,*=,%=
@=1.x,<=,^=,+=,|=,?=,*=,%=
#MAKE#: Nothing to be done for 'all'.\n");
1;

View file

@ -325,5 +325,103 @@ 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");
# This tells the test driver that the perl test script executed properly.
1;