make/tests/scripts/features/double_colon
Paul Smith 4762480ae9 [SV 47995] Ensure forced double-colon rules work with -j.
The fix for SV 44742 had a side-effect that some double-colon targets
were skipped.  This happens because the "considered" facility assumed
that all targets would be visited on each walk through the dependency
graph: we used a bit for considered and toggled it on each pass; if
we didn't walk the entire graph on every pass the bit would get out
of sync.  The new behavior after SV 44742 might return early without
walking the entire graph.  To fix this I changed the considered value
to an integer which is monotonically increasing: it is then never
possible to incorrectly determine that a previous pass through the
graph already considered the current target.

* filedef.h (struct file): make CONSIDERED an unsigned int.
* main.c (main): No longer need to reset CONSIDERED.
* remake.c (update_goal_chain): increment CONSIDERED rather than
inverting it between 0<->1.
(update_file_1): Reset CONSIDERED to 0 so it's re-considered.
(check_dep): Ditto.
* tests/scripts/features/double_colon: Add a regression test.
2016-05-31 03:17:26 -04:00

221 lines
4.6 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');
# 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: