make/tests/scripts/features/double_colon
Dmitry Goncharov 9e4b3d3f4c [SV 60435] Ensure intermediate grouped files are removed
If multiple intermediate files are built together be sure all of them
are removed after make is finished.  Continue to ensure that targets
that exist before make starts are not removed even if they appear to be
intermediate.

Add a number of tests to pattern rules to verify this behavior.

* src/filedef.h (struct file): Add a new is_explicit bitfield.
* src/file.c (rehash_file): Merge the is_explicit bit.
(enter_prereqs): Set is_explicit if the file is explicitly mentioned.
* src/implicit.c (pattern_search): Set intermediate on the file if it's
not explicit.
(record_files): Set is_explicit if a file is mentioned as a target.
* src/remake.c (update_file_1): Set secondary on files that already
exist so they won't be removed.
* tests/scripts/features/double_colon: Add a test for double-colon
pattern rules.
* tests/scripts/features/patternrules: Update KGO for tests where more
files are removed.
Add new tests to verify handling removal of intermediate files in the
context of grouped pattern targets.
2021-09-07 01:14:20 -04:00

249 lines
5.1 KiB
Perl

# -*-perl-*-
$description = "Test handling of double-colon rules.";
$details = "\
We test these features:
- Multiple commands for the same (double-colon) target
- Different prerequisites for targets: only out-of-date
ones are rebuilt.
- Double-colon targets that aren't the goal target.
Then we do the same thing for parallel builds: double-colon
targets should always be built serially.";
# The Contents of the MAKEFILE ...
open(MAKEFILE,"> $makefile");
print MAKEFILE <<'EOF';
all: baz
foo:: f1.h ; @echo foo FIRST
foo:: f2.h ; @echo foo SECOND
bar:: ; @echo aaa; sleep 1; echo aaa done
bar:: ; @echo bbb
baz:: ; @echo aaa
baz:: ; @echo bbb
biz:: ; @echo aaa
biz:: two ; @echo bbb
two: ; @echo two
f1.h f2.h: ; @echo $@
d :: ; @echo ok
d :: d ; @echo oops
EOF
close(MAKEFILE);
# TEST 0: A simple double-colon rule that isn't the goal target.
&run_make_with_options($makefile, "all", &get_logfile, 0);
$answer = "aaa\nbbb\n";
&compare_output($answer, &get_logfile(1));
# TEST 1: As above, in parallel
if ($parallel_jobs) {
&run_make_with_options($makefile, "-j10 all", &get_logfile, 0);
$answer = "aaa\nbbb\n";
&compare_output($answer, &get_logfile(1));
}
# TEST 2: A simple double-colon rule that is the goal target
&run_make_with_options($makefile, "bar", &get_logfile, 0);
$answer = "aaa\naaa done\nbbb\n";
&compare_output($answer, &get_logfile(1));
# TEST 3: As above, in parallel
if ($parallel_jobs) {
&run_make_with_options($makefile, "-j10 bar", &get_logfile, 0);
$answer = "aaa\naaa done\nbbb\n";
&compare_output($answer, &get_logfile(1));
}
# TEST 4: Each double-colon rule is supposed to be run individually
&utouch(-5, 'f2.h');
&touch('foo');
&run_make_with_options($makefile, "foo", &get_logfile, 0);
$answer = "f1.h\nfoo FIRST\n";
&compare_output($answer, &get_logfile(1));
# TEST 5: Again, in parallel.
if ($parallel_jobs) {
&run_make_with_options($makefile, "-j10 foo", &get_logfile, 0);
$answer = "f1.h\nfoo FIRST\n";
&compare_output($answer, &get_logfile(1));
}
# TEST 6: Each double-colon rule is supposed to be run individually
&utouch(-5, 'f1.h');
unlink('f2.h');
&touch('foo');
&run_make_with_options($makefile, "foo", &get_logfile, 0);
$answer = "f2.h\nfoo SECOND\n";
&compare_output($answer, &get_logfile(1));
# TEST 7: Again, in parallel.
if ($parallel_jobs) {
&run_make_with_options($makefile, "-j10 foo", &get_logfile, 0);
$answer = "f2.h\nfoo SECOND\n";
&compare_output($answer, &get_logfile(1));
}
# TEST 8: Test circular dependency check; PR/1671
&run_make_with_options($makefile, "d", &get_logfile, 0);
$answer = "ok\n$make_name: Circular d <- d dependency dropped.\noops\n";
&compare_output($answer, &get_logfile(1));
# TEST 8: I don't grok why this is different than the above, but it is...
#
# Hmm... further testing indicates this might be timing-dependent?
#
#if ($parallel_jobs) {
# &run_make_with_options($makefile, "-j10 biz", &get_logfile, 0);
# $answer = "aaa\ntwo\nbbb\n";
# &compare_output($answer, &get_logfile(1));
#}
unlink('foo','f1.h','f2.h');
# TEST 9: make sure all rules in s double colon family get executed
# (Savannah bug #14334).
#
&touch('one');
&touch('two');
run_make_test('
.PHONY: all
all: result
result:: one
@echo $^ >>$@
@echo $^
result:: two
@echo $^ >>$@
@echo $^
',
'',
'one
two');
unlink('result','one','two');
# TEST 10: SV 33399 : check for proper backslash handling
run_make_test('
a\ xb :: ; @echo one
a\ xb :: ; @echo two
',
'', "one\ntwo\n");
# Test 11: SV 44742 : All double-colon rules should be run in parallel build.
run_make_test('result :: 01
@echo update
@touch $@
result :: 02
@echo update
@touch $@
result :: 03
@echo update
@touch $@
result :: 04
@echo update
@touch $@
result :: 05
@echo update
@touch $@
01 02 03 04 05:
@touch 01 02 03 04 05
',
'-j10 result', "update\nupdate\nupdate\nupdate\nupdate\n");
unlink('result', '01', '02', '03', '04', '05');
# Test 12: SV 44742 : Double-colon rules with parallelism
run_make_test('
root: all
echo root
all::
echo all_one
all:: 3
echo all_two
%:
sleep $*
',
'-rs -j2 1 2 root', "all_one\nall_two\nroot\n");
# SV 47995 : Parallel double-colon rules with FORCE
run_make_test('
all:: ; @echo one
all:: joe ; @echo four
joe: FORCE ; touch joe-is-forced
FORCE:
',
'-j5', "one\ntouch joe-is-forced\nfour\n");
unlink('joe-is-forced');
# sv 60188.
# Even though test.x is explicitly mentioned, terminal pattern rules still
# apply only if the prerequisite exists.
touch('hello.z');
# subtest 1. test.x is explicitly mentioned.
run_make_test(q!
all: hello.z
%.z:: test.x ; touch $@
%.x: ;
!,
'', "#MAKE#: Nothing to be done for 'all'.\n");
unlink('hello.z');
# subtest 2. hello.x is derived from the stem.
touch('hello.z');
run_make_test(q!
all: hello.z
%.z:: %.x; touch $@
%.x: ; touch $@
!,
'', "#MAKE#: Nothing to be done for 'all'.\n");
unlink('hello.z');
# This tells the test driver that the perl test script executed properly.
1;
### Local Variables:
### eval: (setq whitespace-action (delq 'auto-cleanup whitespace-action))
### End: