make/tests/scripts/targets/WAIT

642 lines
21 KiB
Plaintext
Raw Normal View History

[SV 13862] Implement the .WAIT special target The next version of the POSIX standard defines parallel execution and requires the .WAIT special target as is implemented in some other versions of make. This implementation behaves similarly to others in that it does not create a relationship between targets in the dependency graph, so that the same two targets may be run in parallel if they appear as prerequisites elsewhere without .WAIT between them. Now that we support .WAIT it's trivial to also support prerequisites of the .NOTPARALLEL special target, which forces the prerequisites of those targets to be run serially (as if .WAIT was specified between each one). * NEWS: Announce the new .WAIT and .NOTPARALLEL support. * doc/make.texi (Parallel Disable): A new section to discuss ways in which parallel execution can be controlled. Modify cross-refs to refer to this section. * src/dep.h (struct dep): Add a new wait_here boolean. (parse_file_seq): Add PARSEFS_WAIT to check for .WAIT dependencies. * src/file.c (split_prereqs): Use PARSEFS_WAIT. (snap_deps): If .NOTPARALLEL has prerequisites, set .WAIT between each of _their_ prerequisites. (print_prereqs): Add back in .WAIT when printing prerequisites. * src/implicit.c (struct patdeps): Preserve wait_here. (pattern_search): Ditto. Use PARSEFS_WAIT when parsing prereqs for pattern rule expansion. * src/read.c (check_specials): Don't give up early: remembering to update these options is not worth the rare speedup. (check_special_file): If .WAIT is given as a target show an error-- once--if it has prereqs or commands. (record_files): Call check_special_file on each target. (parse_file_seq): If PARSEFS_WAIT is given, look for .WAIT prereqs. If we see one assume that we are building a struct dep chain and set the wait_here option while not putting it into the list. * src/remake.c (update_file_1): If wait_here is set and we are still running, then stop trying to build this target's prerequisites. * src/rule.c (get_rule_defn): Add .WAIT to the prerequisite list. * src/shuffle.c (shuffle_deps): Don't shuffle the prerequisite list if .WAIT appears anywhere in it. * tests/scripts/targets/WAIT: Add a test suite for this feature.
2022-09-13 06:18:49 +08:00
# -*-perl-*-
$description = "Test the behaviour of the .WAIT target.";
$details = "";
# Ensure .WAIT doesn't appear in any automatic variables
run_make_test(q!
all: .WAIT pre1 .WAIT pre2 | .WAIT pre3 ; @echo '<=$< ^=$^ ?=$? +=$+ |=$|'
pre1 pre2 pre3:;
# This is just here so we don't fail with older versions of make
.WAIT:
!,
'', '<=pre1 ^=pre1 pre2 ?=pre1 pre2 +=pre1 pre2 |=pre3');
run_make_test(q!
.SECONDEXPANSION:
all: $$(pre) ; @echo '<=$< ^=$^ ?=$? +=$+ |=$|'
pre1 pre2 pre3:;
pre = .WAIT pre1 .WAIT pre2 | .WAIT pre3
# This is just here so we don't fail with older versions of make
.WAIT:
!,
'', '<=pre1 ^=pre1 pre2 ?=pre1 pre2 +=pre1 pre2 |=pre3');
run_make_test(q!
all: pre
p% : .WAIT p%1 .WAIT p%2 | .WAIT p%3; @echo '<=$< ^=$^ ?=$? +=$+ |=$|'
pre1 pre2 pre3: ;
# This is just here so we don't fail with older versions of make
.WAIT:
!,
'', "<=pre1 ^=pre1 pre2 ?=pre1 pre2 +=pre1 pre2 |=pre3\n");
# Unfortunately I don't think we can get away from using sleep here; at least
# I can't think of any way to make sure .WAIT works without it. Even with it,
# it's not reliable (in that even if .WAIT is not working we MIGHT succeed the
# test--it shouldn't ever be the case that we fail the test unexpectedly).
# That makes this test suite slow to run :-/.
run_make_test(q!
all : pre1 .WAIT pre2
pre1: ; @#HELPER# -q out start-$@ sleep 1 out end-$@
pre2: ; @#HELPER# -q out $@
# This is just here so we don't fail with older versions of make
.WAIT:
!,
'-j10', "start-pre1\nend-pre1\npre2\n");
# Ensure .WAIT doesn't add extra a dependency between its targets
run_make_test(undef, '-j10 pre2', "pre2\n");
# sv 63856.
# .WAIT on the command line.
run_make_test(q!
pre1: ; @#HELPER# -q out start-$@ sleep 1 out end-$@
pre2: ; @#HELPER# -q out $@
# This is just here so we don't fail with older versions of make
.WAIT:
!,
'-j10 pre1 .WAIT pre2', "start-pre1\nend-pre1\npre2\n");
# Multiple consecutive .WAITs.
run_make_test(q!
all : pre1 .WAIT .WAIT .WAIT pre2
pre1: ; @#HELPER# -q out start-$@ sleep 1 out end-$@
pre2: ; @#HELPER# -q out $@
# This is just here so we don't fail with older versions of make
.WAIT:
!,
'-j10', "start-pre1\nend-pre1\npre2\n");
# First and last prerequsites are .WAIT.
run_make_test(q!
all : .WAIT pre1 .WAIT pre2 .WAIT
pre1: ; @#HELPER# -q out start-$@ sleep 1 out end-$@
pre2: ; @#HELPER# -q out $@
# This is just here so we don't fail with older versions of make
.WAIT:
!,
'-j10', "start-pre1\nend-pre1\npre2\n");
# All prerequisites are .WAITs.
run_make_test(q!
all : .WAIT .WAIT .WAIT
# This is just here so we don't fail with older versions of make
.WAIT:
!,
'-j10', "#MAKE#: Nothing to be done for 'all'.\n");
run_make_test(q!
all:
!,
'-j10 .WAIT', "#MAKE#: Nothing to be done for 'all'.\n");
# Wait between the duplicate goals.
run_make_test(q!
all: hello.tsk .WAIT hello.tsk
hello.tsk:; $(info $@)
!,
'-j10', "hello.tsk\n#MAKE#: Nothing to be done for 'all'.\n");
# Wait between the duplicate command line goals.
run_make_test(q!
hello.tsk:; $(info $@)
!,
'-j10 hello.tsk .WAIT hello.tsk', "hello.tsk\n#MAKE#: 'hello.tsk' is up to date.\n#MAKE#: 'hello.tsk' is up to date.\n");
[SV 13862] Implement the .WAIT special target The next version of the POSIX standard defines parallel execution and requires the .WAIT special target as is implemented in some other versions of make. This implementation behaves similarly to others in that it does not create a relationship between targets in the dependency graph, so that the same two targets may be run in parallel if they appear as prerequisites elsewhere without .WAIT between them. Now that we support .WAIT it's trivial to also support prerequisites of the .NOTPARALLEL special target, which forces the prerequisites of those targets to be run serially (as if .WAIT was specified between each one). * NEWS: Announce the new .WAIT and .NOTPARALLEL support. * doc/make.texi (Parallel Disable): A new section to discuss ways in which parallel execution can be controlled. Modify cross-refs to refer to this section. * src/dep.h (struct dep): Add a new wait_here boolean. (parse_file_seq): Add PARSEFS_WAIT to check for .WAIT dependencies. * src/file.c (split_prereqs): Use PARSEFS_WAIT. (snap_deps): If .NOTPARALLEL has prerequisites, set .WAIT between each of _their_ prerequisites. (print_prereqs): Add back in .WAIT when printing prerequisites. * src/implicit.c (struct patdeps): Preserve wait_here. (pattern_search): Ditto. Use PARSEFS_WAIT when parsing prereqs for pattern rule expansion. * src/read.c (check_specials): Don't give up early: remembering to update these options is not worth the rare speedup. (check_special_file): If .WAIT is given as a target show an error-- once--if it has prereqs or commands. (record_files): Call check_special_file on each target. (parse_file_seq): If PARSEFS_WAIT is given, look for .WAIT prereqs. If we see one assume that we are building a struct dep chain and set the wait_here option while not putting it into the list. * src/remake.c (update_file_1): If wait_here is set and we are still running, then stop trying to build this target's prerequisites. * src/rule.c (get_rule_defn): Add .WAIT to the prerequisite list. * src/shuffle.c (shuffle_deps): Don't shuffle the prerequisite list if .WAIT appears anywhere in it. * tests/scripts/targets/WAIT: Add a test suite for this feature.
2022-09-13 06:18:49 +08:00
# Ensure .WAIT doesn't wait between all targets
run_make_test(q!
all : pre1 .WAIT pre2 pre3
pre1: ; @#HELPER# -q out start-$@ sleep 1 out end-$@
pre2: ; @#HELPER# -q out start-$@ file TWO wait THREE out end-$@
pre3: ; @#HELPER# -q wait TWO out $@ file THREE
# This is just here so we don't fail with older versions of make
.WAIT:
!,
'-j10', "start-pre1\nend-pre1\nstart-pre2\npre3\nend-pre2\n");
unlink(qw(TWO THREE));
# Ensure .WAIT on the command line doesn't wait between all targets.
run_make_test(q!
pre1: ; @#HELPER# -q out start-$@ sleep 1 out end-$@
pre2: ; @#HELPER# -q out start-$@ file TWO wait THREE out end-$@
pre3: ; @#HELPER# -q wait TWO out $@ file THREE
# This is just here so we don't fail with older versions of make
.WAIT:
!,
'-j10 pre1 .WAIT pre2 pre3', "start-pre1\nend-pre1\nstart-pre2\npre3\nend-pre2\n");
unlink(qw(TWO THREE));
[SV 13862] Implement the .WAIT special target The next version of the POSIX standard defines parallel execution and requires the .WAIT special target as is implemented in some other versions of make. This implementation behaves similarly to others in that it does not create a relationship between targets in the dependency graph, so that the same two targets may be run in parallel if they appear as prerequisites elsewhere without .WAIT between them. Now that we support .WAIT it's trivial to also support prerequisites of the .NOTPARALLEL special target, which forces the prerequisites of those targets to be run serially (as if .WAIT was specified between each one). * NEWS: Announce the new .WAIT and .NOTPARALLEL support. * doc/make.texi (Parallel Disable): A new section to discuss ways in which parallel execution can be controlled. Modify cross-refs to refer to this section. * src/dep.h (struct dep): Add a new wait_here boolean. (parse_file_seq): Add PARSEFS_WAIT to check for .WAIT dependencies. * src/file.c (split_prereqs): Use PARSEFS_WAIT. (snap_deps): If .NOTPARALLEL has prerequisites, set .WAIT between each of _their_ prerequisites. (print_prereqs): Add back in .WAIT when printing prerequisites. * src/implicit.c (struct patdeps): Preserve wait_here. (pattern_search): Ditto. Use PARSEFS_WAIT when parsing prereqs for pattern rule expansion. * src/read.c (check_specials): Don't give up early: remembering to update these options is not worth the rare speedup. (check_special_file): If .WAIT is given as a target show an error-- once--if it has prereqs or commands. (record_files): Call check_special_file on each target. (parse_file_seq): If PARSEFS_WAIT is given, look for .WAIT prereqs. If we see one assume that we are building a struct dep chain and set the wait_here option while not putting it into the list. * src/remake.c (update_file_1): If wait_here is set and we are still running, then stop trying to build this target's prerequisites. * src/rule.c (get_rule_defn): Add .WAIT to the prerequisite list. * src/shuffle.c (shuffle_deps): Don't shuffle the prerequisite list if .WAIT appears anywhere in it. * tests/scripts/targets/WAIT: Add a test suite for this feature.
2022-09-13 06:18:49 +08:00
# Ensure .WAIT waits for ALL targets on the left before ANY targets on the right
run_make_test(q!
all : pre1 pre2 .WAIT post1 post2
pre1: ; @#HELPER# -q out start-$@ file PRE1 wait PRE2 sleep 1 out end-$@
pre2: ; @#HELPER# -q wait PRE1 out $@ file PRE2
post1: ; @#HELPER# -q wait POST2 out $@ file POST1
post2: ; @#HELPER# -q file POST2 wait POST1 out $@
# This is just here so we don't fail with older versions of make
.WAIT:
!,
'-j10', "start-pre1\npre2\nend-pre1\npost1\npost2\n");
unlink(qw(PRE1 PRE2 POST1 POST2));
# Ensure .WAIT on the command line waits for ALL targets on the left before ANY
# targets on the right.
run_make_test(q!
pre1: ; @#HELPER# -q out start-$@ file PRE1 wait PRE2 sleep 1 out end-$@
pre2: ; @#HELPER# -q wait PRE1 out $@ file PRE2
post1: ; @#HELPER# -q wait POST2 out $@ file POST1
post2: ; @#HELPER# -q file POST2 wait POST1 out $@
# This is just here so we don't fail with older versions of make
.WAIT:
!,
'-j10 pre1 pre2 .WAIT post1 post2', "start-pre1\npre2\nend-pre1\npost1\npost2\n");
unlink(qw(PRE1 PRE2 POST1 POST2));
[SV 13862] Implement the .WAIT special target The next version of the POSIX standard defines parallel execution and requires the .WAIT special target as is implemented in some other versions of make. This implementation behaves similarly to others in that it does not create a relationship between targets in the dependency graph, so that the same two targets may be run in parallel if they appear as prerequisites elsewhere without .WAIT between them. Now that we support .WAIT it's trivial to also support prerequisites of the .NOTPARALLEL special target, which forces the prerequisites of those targets to be run serially (as if .WAIT was specified between each one). * NEWS: Announce the new .WAIT and .NOTPARALLEL support. * doc/make.texi (Parallel Disable): A new section to discuss ways in which parallel execution can be controlled. Modify cross-refs to refer to this section. * src/dep.h (struct dep): Add a new wait_here boolean. (parse_file_seq): Add PARSEFS_WAIT to check for .WAIT dependencies. * src/file.c (split_prereqs): Use PARSEFS_WAIT. (snap_deps): If .NOTPARALLEL has prerequisites, set .WAIT between each of _their_ prerequisites. (print_prereqs): Add back in .WAIT when printing prerequisites. * src/implicit.c (struct patdeps): Preserve wait_here. (pattern_search): Ditto. Use PARSEFS_WAIT when parsing prereqs for pattern rule expansion. * src/read.c (check_specials): Don't give up early: remembering to update these options is not worth the rare speedup. (check_special_file): If .WAIT is given as a target show an error-- once--if it has prereqs or commands. (record_files): Call check_special_file on each target. (parse_file_seq): If PARSEFS_WAIT is given, look for .WAIT prereqs. If we see one assume that we are building a struct dep chain and set the wait_here option while not putting it into the list. * src/remake.c (update_file_1): If wait_here is set and we are still running, then stop trying to build this target's prerequisites. * src/rule.c (get_rule_defn): Add .WAIT to the prerequisite list. * src/shuffle.c (shuffle_deps): Don't shuffle the prerequisite list if .WAIT appears anywhere in it. * tests/scripts/targets/WAIT: Add a test suite for this feature.
2022-09-13 06:18:49 +08:00
# See if .WAIT takes effect between different lists of prereqs
# In the current implementation, .WAIT waits only between two prerequisites
# in a given target. These same two targets might be run in a different
# order if they appear as prerequisites of another target. This is the way
# other implementations of .WAIT work. I personally think it's gross and
# makes .WAIT just a toy when it comes to ordering, but it's much simpler
# to implement than creating an actual edge in the DAG to represent .WAIT
# and since that's what users expect, we'll do the same for now.
run_make_test(q!
all : one two
one: pre1 .WAIT pre2
two: pre2 pre1
pre1: ; @#HELPER# -q out start-$@ file PRE1 wait PRE2 out end-$@
pre2: ; @#HELPER# -q wait PRE1 out $@ file PRE2
[SV 13862] Implement the .WAIT special target The next version of the POSIX standard defines parallel execution and requires the .WAIT special target as is implemented in some other versions of make. This implementation behaves similarly to others in that it does not create a relationship between targets in the dependency graph, so that the same two targets may be run in parallel if they appear as prerequisites elsewhere without .WAIT between them. Now that we support .WAIT it's trivial to also support prerequisites of the .NOTPARALLEL special target, which forces the prerequisites of those targets to be run serially (as if .WAIT was specified between each one). * NEWS: Announce the new .WAIT and .NOTPARALLEL support. * doc/make.texi (Parallel Disable): A new section to discuss ways in which parallel execution can be controlled. Modify cross-refs to refer to this section. * src/dep.h (struct dep): Add a new wait_here boolean. (parse_file_seq): Add PARSEFS_WAIT to check for .WAIT dependencies. * src/file.c (split_prereqs): Use PARSEFS_WAIT. (snap_deps): If .NOTPARALLEL has prerequisites, set .WAIT between each of _their_ prerequisites. (print_prereqs): Add back in .WAIT when printing prerequisites. * src/implicit.c (struct patdeps): Preserve wait_here. (pattern_search): Ditto. Use PARSEFS_WAIT when parsing prereqs for pattern rule expansion. * src/read.c (check_specials): Don't give up early: remembering to update these options is not worth the rare speedup. (check_special_file): If .WAIT is given as a target show an error-- once--if it has prereqs or commands. (record_files): Call check_special_file on each target. (parse_file_seq): If PARSEFS_WAIT is given, look for .WAIT prereqs. If we see one assume that we are building a struct dep chain and set the wait_here option while not putting it into the list. * src/remake.c (update_file_1): If wait_here is set and we are still running, then stop trying to build this target's prerequisites. * src/rule.c (get_rule_defn): Add .WAIT to the prerequisite list. * src/shuffle.c (shuffle_deps): Don't shuffle the prerequisite list if .WAIT appears anywhere in it. * tests/scripts/targets/WAIT: Add a test suite for this feature.
2022-09-13 06:18:49 +08:00
# This is just here so we don't fail with older versions of make
.WAIT:
!,
'-j10', "start-pre1\npre2\nend-pre1\n");
unlink(qw(PRE1 PRE2));
[SV 13862] Implement the .WAIT special target The next version of the POSIX standard defines parallel execution and requires the .WAIT special target as is implemented in some other versions of make. This implementation behaves similarly to others in that it does not create a relationship between targets in the dependency graph, so that the same two targets may be run in parallel if they appear as prerequisites elsewhere without .WAIT between them. Now that we support .WAIT it's trivial to also support prerequisites of the .NOTPARALLEL special target, which forces the prerequisites of those targets to be run serially (as if .WAIT was specified between each one). * NEWS: Announce the new .WAIT and .NOTPARALLEL support. * doc/make.texi (Parallel Disable): A new section to discuss ways in which parallel execution can be controlled. Modify cross-refs to refer to this section. * src/dep.h (struct dep): Add a new wait_here boolean. (parse_file_seq): Add PARSEFS_WAIT to check for .WAIT dependencies. * src/file.c (split_prereqs): Use PARSEFS_WAIT. (snap_deps): If .NOTPARALLEL has prerequisites, set .WAIT between each of _their_ prerequisites. (print_prereqs): Add back in .WAIT when printing prerequisites. * src/implicit.c (struct patdeps): Preserve wait_here. (pattern_search): Ditto. Use PARSEFS_WAIT when parsing prereqs for pattern rule expansion. * src/read.c (check_specials): Don't give up early: remembering to update these options is not worth the rare speedup. (check_special_file): If .WAIT is given as a target show an error-- once--if it has prereqs or commands. (record_files): Call check_special_file on each target. (parse_file_seq): If PARSEFS_WAIT is given, look for .WAIT prereqs. If we see one assume that we are building a struct dep chain and set the wait_here option while not putting it into the list. * src/remake.c (update_file_1): If wait_here is set and we are still running, then stop trying to build this target's prerequisites. * src/rule.c (get_rule_defn): Add .WAIT to the prerequisite list. * src/shuffle.c (shuffle_deps): Don't shuffle the prerequisite list if .WAIT appears anywhere in it. * tests/scripts/targets/WAIT: Add a test suite for this feature.
2022-09-13 06:18:49 +08:00
# Check that .WAIT works with pattern rules
run_make_test(q!
all: pre
p% : p%1 .WAIT p%2;
pre1: ; @#HELPER# -q out start-$@ sleep 1 out end-$@
pre2: ; @#HELPER# -q out $@
# This is just here so we don't fail with older versions of make
.WAIT:
!,
'-j10', "start-pre1\nend-pre1\npre2\n");
# Check that .WAIT works with secondarily expanded rules
run_make_test(q!
.SECONDEXPANSION:
all: $$(pre)
pre1: ; @#HELPER# -q out start-$@ sleep 1 out end-$@
pre2: ; @#HELPER# -q out $@
pre3: ; @#HELPER# -q out $@
pre = .WAIT pre1 .WAIT pre2 | .WAIT pre3
# This is just here so we don't fail with older versions of make
.WAIT:
!,
'-j10', "start-pre1\nend-pre1\npre2\npre3\n");
# Verify NOTPARALLEL works
run_make_test(q!
all : pre1 pre2
pre1: ; @#HELPER# -q out start-$@ sleep 1 out end-$@
pre2: ; @#HELPER# -q out $@
.NOTPARALLEL:
!,
'-j10', "start-pre1\nend-pre1\npre2\n");
run_make_test(q!
all : p1 .WAIT np1
p1: pre1 pre2
pre1: ; @#HELPER# -q out start-$@ file PRE1 wait PRE2 out end-$@
pre2: ; @#HELPER# -q wait PRE1 out $@ file PRE2
[SV 13862] Implement the .WAIT special target The next version of the POSIX standard defines parallel execution and requires the .WAIT special target as is implemented in some other versions of make. This implementation behaves similarly to others in that it does not create a relationship between targets in the dependency graph, so that the same two targets may be run in parallel if they appear as prerequisites elsewhere without .WAIT between them. Now that we support .WAIT it's trivial to also support prerequisites of the .NOTPARALLEL special target, which forces the prerequisites of those targets to be run serially (as if .WAIT was specified between each one). * NEWS: Announce the new .WAIT and .NOTPARALLEL support. * doc/make.texi (Parallel Disable): A new section to discuss ways in which parallel execution can be controlled. Modify cross-refs to refer to this section. * src/dep.h (struct dep): Add a new wait_here boolean. (parse_file_seq): Add PARSEFS_WAIT to check for .WAIT dependencies. * src/file.c (split_prereqs): Use PARSEFS_WAIT. (snap_deps): If .NOTPARALLEL has prerequisites, set .WAIT between each of _their_ prerequisites. (print_prereqs): Add back in .WAIT when printing prerequisites. * src/implicit.c (struct patdeps): Preserve wait_here. (pattern_search): Ditto. Use PARSEFS_WAIT when parsing prereqs for pattern rule expansion. * src/read.c (check_specials): Don't give up early: remembering to update these options is not worth the rare speedup. (check_special_file): If .WAIT is given as a target show an error-- once--if it has prereqs or commands. (record_files): Call check_special_file on each target. (parse_file_seq): If PARSEFS_WAIT is given, look for .WAIT prereqs. If we see one assume that we are building a struct dep chain and set the wait_here option while not putting it into the list. * src/remake.c (update_file_1): If wait_here is set and we are still running, then stop trying to build this target's prerequisites. * src/rule.c (get_rule_defn): Add .WAIT to the prerequisite list. * src/shuffle.c (shuffle_deps): Don't shuffle the prerequisite list if .WAIT appears anywhere in it. * tests/scripts/targets/WAIT: Add a test suite for this feature.
2022-09-13 06:18:49 +08:00
np1: npre1 npre2
npre1: ; @#HELPER# -q out start-$@ sleep 1 out end-$@
npre2: ; @#HELPER# -q out $@
.NOTPARALLEL: np1
!,
'-j10', "start-pre1\npre2\nend-pre1\nstart-npre1\nend-npre1\nnpre2\n");
unlink(qw(PRE1 PRE2));
[SV 13862] Implement the .WAIT special target The next version of the POSIX standard defines parallel execution and requires the .WAIT special target as is implemented in some other versions of make. This implementation behaves similarly to others in that it does not create a relationship between targets in the dependency graph, so that the same two targets may be run in parallel if they appear as prerequisites elsewhere without .WAIT between them. Now that we support .WAIT it's trivial to also support prerequisites of the .NOTPARALLEL special target, which forces the prerequisites of those targets to be run serially (as if .WAIT was specified between each one). * NEWS: Announce the new .WAIT and .NOTPARALLEL support. * doc/make.texi (Parallel Disable): A new section to discuss ways in which parallel execution can be controlled. Modify cross-refs to refer to this section. * src/dep.h (struct dep): Add a new wait_here boolean. (parse_file_seq): Add PARSEFS_WAIT to check for .WAIT dependencies. * src/file.c (split_prereqs): Use PARSEFS_WAIT. (snap_deps): If .NOTPARALLEL has prerequisites, set .WAIT between each of _their_ prerequisites. (print_prereqs): Add back in .WAIT when printing prerequisites. * src/implicit.c (struct patdeps): Preserve wait_here. (pattern_search): Ditto. Use PARSEFS_WAIT when parsing prereqs for pattern rule expansion. * src/read.c (check_specials): Don't give up early: remembering to update these options is not worth the rare speedup. (check_special_file): If .WAIT is given as a target show an error-- once--if it has prereqs or commands. (record_files): Call check_special_file on each target. (parse_file_seq): If PARSEFS_WAIT is given, look for .WAIT prereqs. If we see one assume that we are building a struct dep chain and set the wait_here option while not putting it into the list. * src/remake.c (update_file_1): If wait_here is set and we are still running, then stop trying to build this target's prerequisites. * src/rule.c (get_rule_defn): Add .WAIT to the prerequisite list. * src/shuffle.c (shuffle_deps): Don't shuffle the prerequisite list if .WAIT appears anywhere in it. * tests/scripts/targets/WAIT: Add a test suite for this feature.
2022-09-13 06:18:49 +08:00
# Ensure we don't shuffle if .WAIT is set
run_make_test(q!
all : pre1 .WAIT pre2
pre1: ; @#HELPER# -q out start-$@ sleep 1 out end-$@
pre2: ; @#HELPER# -q out $@
# This is just here so we don't fail with older versions of make
.WAIT:
!,
'-j10 --shuffle=reverse', "start-pre1\nend-pre1\npre2\n");
# Ensure we don't shuffle if .WAIT is set on the command line.
run_make_test(q!
pre1: ; @#HELPER# -q out start-$@ sleep 1 out end-$@
pre2: ; @#HELPER# -q out $@
# This is just here so we don't fail with older versions of make
.WAIT:
!,
'-j10 --shuffle=reverse pre1 .WAIT pre2', "start-pre1\nend-pre1\npre2\n");
[SV 13862] Implement the .WAIT special target The next version of the POSIX standard defines parallel execution and requires the .WAIT special target as is implemented in some other versions of make. This implementation behaves similarly to others in that it does not create a relationship between targets in the dependency graph, so that the same two targets may be run in parallel if they appear as prerequisites elsewhere without .WAIT between them. Now that we support .WAIT it's trivial to also support prerequisites of the .NOTPARALLEL special target, which forces the prerequisites of those targets to be run serially (as if .WAIT was specified between each one). * NEWS: Announce the new .WAIT and .NOTPARALLEL support. * doc/make.texi (Parallel Disable): A new section to discuss ways in which parallel execution can be controlled. Modify cross-refs to refer to this section. * src/dep.h (struct dep): Add a new wait_here boolean. (parse_file_seq): Add PARSEFS_WAIT to check for .WAIT dependencies. * src/file.c (split_prereqs): Use PARSEFS_WAIT. (snap_deps): If .NOTPARALLEL has prerequisites, set .WAIT between each of _their_ prerequisites. (print_prereqs): Add back in .WAIT when printing prerequisites. * src/implicit.c (struct patdeps): Preserve wait_here. (pattern_search): Ditto. Use PARSEFS_WAIT when parsing prereqs for pattern rule expansion. * src/read.c (check_specials): Don't give up early: remembering to update these options is not worth the rare speedup. (check_special_file): If .WAIT is given as a target show an error-- once--if it has prereqs or commands. (record_files): Call check_special_file on each target. (parse_file_seq): If PARSEFS_WAIT is given, look for .WAIT prereqs. If we see one assume that we are building a struct dep chain and set the wait_here option while not putting it into the list. * src/remake.c (update_file_1): If wait_here is set and we are still running, then stop trying to build this target's prerequisites. * src/rule.c (get_rule_defn): Add .WAIT to the prerequisite list. * src/shuffle.c (shuffle_deps): Don't shuffle the prerequisite list if .WAIT appears anywhere in it. * tests/scripts/targets/WAIT: Add a test suite for this feature.
2022-09-13 06:18:49 +08:00
# Warn about invalid .WAIT definitions
run_make_test(q!
.WAIT: foo
.WAIT: ; echo oops
all:;@:
!,
'', "#MAKEFILE#:2: .WAIT should not have prerequisites\n#MAKEFILE#:3: .WAIT should not have commands\n");
# Wait for all double colon targets on the left, before building targets on the
# right.
# Subtest 1. First run this test without .WAIT and observe and A recipes
# interleave with B recipes.
# Then run the same test with .WAIT and observe that all A recipes get started
# sequentially before the 1st B recipe gets started and then all B recipes get
# started sequentially.
unlink('A-1-done', 'A-2-done', 'A-3-done', 'B-1-done', 'B-2-done', 'B-3-done');
run_make_test(q!
all: A B
A ::; @#HELPER# -q out A-1 file A-1-done wait B-1-done out A-1-done
A ::; @#HELPER# -q out A-2 file A-2-done wait B-2-done out A-2-done
A ::; @#HELPER# -q out A-3 file A-3-done wait B-3-done out A-3-done
B ::; @#HELPER# -q wait A-1-done out B-1 out B-1-done file B-1-done
B ::; @#HELPER# -q wait A-2-done out B-2 out B-2-done file B-2-done
B ::; @#HELPER# -q wait A-3-done out B-3 out B-3-done file B-3-done
# This is just here so we don't fail with older versions of make
.WAIT:
!,
'-j10', "A-1\nB-1\nB-1-done\nA-1-done\nA-2\nB-2\nB-2-done\nA-2-done\nA-3\nB-3\nB-3-done\nA-3-done\n");
unlink('A-1-done', 'A-2-done', 'A-3-done', 'B-1-done', 'B-2-done', 'B-3-done');
# Subtest 2.
# Wait for all double colon targets on the left, before building targets on the
# right.
run_make_test(q!
all: A .WAIT B
A ::; @#HELPER# -q out $@-1 out $@-1-done
A ::; @#HELPER# -q out $@-2 out $@-2-done
A ::; @#HELPER# -q out $@-3 out $@-3-done
B ::; @#HELPER# -q out $@-1 out $@-1-done
B ::; @#HELPER# -q out $@-2 out $@-2-done
B ::; @#HELPER# -q out $@-3 out $@-3-done
# This is just here so we don't fail with older versions of make
.WAIT:
!,
'-j10', "A-1\nA-1-done\nA-2\nA-2-done\nA-3\nA-3-done\nB-1\nB-1-done\nB-2\nB-2-done\nB-3\nB-3-done\n");
# sv 63856.
# Wait for all double colon targets on the left, before building targets on the
# right.
# Subtest 1. First run this test without .WAIT and observe and A recipes
# interleave with B recipes.
# Then run the same test with .WAIT and observe that all A recipes get started
# sequentially before the 1st B recipe gets started and then all B recipes get
# started sequentially.
# The targets are specified on the command line.
unlink('A-1-done', 'A-2-done', 'A-3-done', 'B-1-done', 'B-2-done', 'B-3-done');
run_make_test(q!
A ::; @#HELPER# -q out A-1 file A-1-done wait B-1-done out A-1-done
A ::; @#HELPER# -q out A-2 file A-2-done wait B-2-done out A-2-done
A ::; @#HELPER# -q out A-3 file A-3-done wait B-3-done out A-3-done
B ::; @#HELPER# -q wait A-1-done out B-1 out B-1-done file B-1-done
B ::; @#HELPER# -q wait A-2-done out B-2 out B-2-done file B-2-done
B ::; @#HELPER# -q wait A-3-done out B-3 out B-3-done file B-3-done
# This is just here so we don't fail with older versions of make
.WAIT:
!,
'-j10 A B', "A-1\nB-1\nB-1-done\nA-1-done\nA-2\nB-2\nB-2-done\nA-2-done\nA-3\nB-3\nB-3-done\nA-3-done\n");
unlink('A-1-done', 'A-2-done', 'A-3-done', 'B-1-done', 'B-2-done', 'B-3-done');
# Subtest 2.
# sv 63856.
# Wait for all double colon targets on the left, before building targets on the
# right. The targets are specified on the command line.
run_make_test(q!
A ::; @#HELPER# -q out $@-1 out $@-1-done
A ::; @#HELPER# -q out $@-2 out $@-2-done
A ::; @#HELPER# -q out $@-3 out $@-3-done
B ::; @#HELPER# -q out $@-1 out $@-1-done
B ::; @#HELPER# -q out $@-2 out $@-2-done
B ::; @#HELPER# -q out $@-3 out $@-3-done
# This is just here so we don't fail with older versions of make
.WAIT:
!,
'-j10 A .WAIT B', "A-1\nA-1-done\nA-2\nA-2-done\nA-3\nA-3-done\nB-1\nB-1-done\nB-2\nB-2-done\nB-3\nB-3-done\n");
# Wait for all double colon targets on the left, before building targets on the
# right.
# Regular targets which have double colon targets as prerequisites.
# Subtest 1. First run this test without .WAIT and observe and A recipes
# interleave with B recipes.
# The targets are specified in the makefile.
unlink('D', 'D-done', 'E', 'E-done');
unlink('A-1-done', 'A-2-done', 'A-3-done', 'B-1-done', 'B-2-done', 'B-3-done');
run_make_test(q!
all: C .WAIT A B
A ::; @#HELPER# -q out A-1 file A-1-done wait B-1-done out A-1-done
A ::; @#HELPER# -q out A-2 file A-2-done wait B-2-done out A-2-done
A ::; @#HELPER# -q out A-3 file A-3-done wait B-3-done out A-3-done
B ::; @#HELPER# -q wait A-1-done out B-1 out B-1-done file B-1-done
B ::; @#HELPER# -q wait A-2-done out B-2 out B-2-done file B-2-done
B ::; @#HELPER# -q wait A-3-done out B-3 out B-3-done file B-3-done
C: D E
D:; @#HELPER# -q out D file D wait E-done out D-done
E:; @#HELPER# -q wait D out E out E-done file E-done
.PHONY: C D E
# This is just here so we don't fail with older versions of make
.WAIT:
!,
'-j10', "D\nE\nE-done\nD-done\nA-1\nB-1\nB-1-done\nA-1-done\nA-2\nB-2\nB-2-done\nA-2-done\nA-3\nB-3\nB-3-done\nA-3-done\n");
# Wait for all double colon targets on the left, before building targets on the
# right.
# Regular targets which have double colon targets as prerequisites.
# Subtest 2.
# Run the same test with .WAIT and observe that all A recipes get started
# sequentially before the 1st B recipe gets started and then all B recipes get
# started sequentially.
# The targets are specified in the makefile.
#
unlink('D', 'D-done', 'E', 'E-done');
unlink('A-1-done', 'A-2-done', 'A-3-done', 'B-1-done', 'B-2-done', 'B-3-done');
run_make_test(q!
all: C .WAIT A .WAIT B
A ::; @#HELPER# -q out $@-1 out $@-1-done
A ::; @#HELPER# -q out $@-2 out $@-2-done
A ::; @#HELPER# -q out $@-3 out $@-3-done
B ::; @#HELPER# -q out $@-1 out $@-1-done
B ::; @#HELPER# -q out $@-2 out $@-2-done
B ::; @#HELPER# -q out $@-3 out $@-3-done
C: D E
D:; @#HELPER# -q out D file D wait E-done out D-done
E:; @#HELPER# -q wait D out E out E-done file E-done
.PHONY: C D E
# This is just here so we don't fail with older versions of make
.WAIT:
!,
'-j10', "D\nE\nE-done\nD-done\nA-1\nA-1-done\nA-2\nA-2-done\nA-3\nA-3-done\nB-1\nB-1-done\nB-2\nB-2-done\nB-3\nB-3-done\n");
# Wait for all double colon targets on the left, before building targets on the
# right.
# Regular targets which have double colon targets as prerequisites.
# Subtest 1. First run this test without .WAIT and observe and A recipes
# interleave with B recipes.
# The targets are specified on the command line.
unlink('D', 'D-done', 'E', 'E-done');
unlink('A-1-done', 'A-2-done', 'A-3-done', 'B-1-done', 'B-2-done', 'B-3-done');
run_make_test(q!
A ::; @#HELPER# -q out A-1 file A-1-done wait B-1-done out A-1-done
A ::; @#HELPER# -q out A-2 file A-2-done wait B-2-done out A-2-done
A ::; @#HELPER# -q out A-3 file A-3-done wait B-3-done out A-3-done
B ::; @#HELPER# -q wait A-1-done out B-1 out B-1-done file B-1-done
B ::; @#HELPER# -q wait A-2-done out B-2 out B-2-done file B-2-done
B ::; @#HELPER# -q wait A-3-done out B-3 out B-3-done file B-3-done
C: D E
D:; @#HELPER# -q out D file D wait E-done out D-done
E:; @#HELPER# -q wait D out E out E-done file E-done
.PHONY: C D E
# This is just here so we don't fail with older versions of make
.WAIT:
!,
'-j10 C .WAIT A B', "D\nE\nE-done\nD-done\nA-1\nB-1\nB-1-done\nA-1-done\nA-2\nB-2\nB-2-done\nA-2-done\nA-3\nB-3\nB-3-done\nA-3-done\n");
# Wait for all double colon targets on the left, before building targets on the
# right.
# Regular targets which have double colon targets as prerequisites.
# Subtest 2.
# Run the same test with .WAIT and observe that all A recipes get started
# sequentially before the 1st B recipe gets started and then all B recipes get
# started sequentially.
# The targets are specified on the command line.
unlink('D', 'D-done', 'E', 'E-done');
unlink('A-1-done', 'A-2-done', 'A-3-done', 'B-1-done', 'B-2-done', 'B-3-done');
run_make_test(q!
A ::; @#HELPER# -q out $@-1 out $@-1-done
A ::; @#HELPER# -q out $@-2 out $@-2-done
A ::; @#HELPER# -q out $@-3 out $@-3-done
B ::; @#HELPER# -q out $@-1 out $@-1-done
B ::; @#HELPER# -q out $@-2 out $@-2-done
B ::; @#HELPER# -q out $@-3 out $@-3-done
C: D E
D:; @#HELPER# -q out D file D wait E-done out D-done
E:; @#HELPER# -q wait D out E out E-done file E-done
.PHONY: C D E
# This is just here so we don't fail with older versions of make
.WAIT:
!,
'-j10 C .WAIT A .WAIT B', "D\nE\nE-done\nD-done\nA-1\nA-1-done\nA-2\nA-2-done\nA-3\nA-3-done\nB-1\nB-1-done\nB-2\nB-2-done\nB-3\nB-3-done\n");
unlink('D', 'D-done', 'E', 'E-done');
unlink('A-1-done', 'A-2-done', 'A-3-done', 'B-1-done', 'B-2-done', 'B-3-done');
# Wait for all double colon targets on the left, before building targets on the
# right.
# Double colon targets have reqular targets as prerequisites.
# Subtest 1. First run this test without .WAIT and observe and A recipes
# interleave with B recipes.
# The targets are specified in the makefile.
unlink('D', 'D-done', 'E', 'E-done');
unlink('A-1-done', 'A-2-done', 'A-3-done', 'B-1-done', 'B-2-done', 'B-3-done');
run_make_test(q!
all: A B
A :: D; @#HELPER# -q out A-1 file A-1-done wait B-1-done out A-1-done
A ::; @#HELPER# -q out A-2 file A-2-done wait B-2-done out A-2-done
A ::; @#HELPER# -q out A-3 file A-3-done wait B-3-done out A-3-done
B :: E; @#HELPER# -q wait A-1-done out B-1 out B-1-done file B-1-done
B ::; @#HELPER# -q wait A-2-done out B-2 out B-2-done file B-2-done
B ::; @#HELPER# -q wait A-3-done out B-3 out B-3-done file B-3-done
D:; @#HELPER# -q out D file D wait E-done out D-done
E:; @#HELPER# -q wait D out E out E-done file E-done
.PHONY: D E
# This is just here so we don't fail with older versions of make
.WAIT:
!,
'-j10', "D\nE\nE-done\nD-done\nA-1\nB-1\nB-1-done\nA-1-done\nA-2\nB-2\nB-2-done\nA-2-done\nA-3\nB-3\nB-3-done\nA-3-done\n");
# Wait for all double colon targets on the left, before building targets on the
# right.
# Double colon targets have reqular targets as prerequisites.
# Subtest 2.
# Run the same test with .WAIT and observe that all A recipes get started
# sequentially before the 1st B recipe gets started and then all B recipes get
# started sequentially.
# The targets are specified in the makefile.
unlink('D', 'D-done', 'E', 'E-done');
unlink('A-1-done', 'A-2-done', 'A-3-done', 'B-1-done', 'B-2-done', 'B-3-done');
run_make_test(q!
all: A .WAIT B
A :: D; @#HELPER# -q out $@-1 out $@-1-done
A :: ; @#HELPER# -q out $@-2 out $@-2-done
A :: ; @#HELPER# -q out $@-3 out $@-3-done
B :: E; @#HELPER# -q out $@-1 out $@-1-done
B :: ; @#HELPER# -q out $@-2 out $@-2-done
B :: ; @#HELPER# -q out $@-3 out $@-3-done
D:; @#HELPER# -q out D out D-done
E:; @#HELPER# -q out E out E-done
.PHONY: D E
# This is just here so we don't fail with older versions of make
.WAIT:
!,
'-j10', "D\nD-done\nA-1\nA-1-done\nA-2\nA-2-done\nA-3\nA-3-done\nE\nE-done\nB-1\nB-1-done\nB-2\nB-2-done\nB-3\nB-3-done\n");
# Wait for all double colon targets on the left, before building targets on the
# right.
# Double colon targets have reqular targets as prerequisites.
# Subtest 1. First run this test without .WAIT and observe and A recipes
# interleave with B recipes.
# The targets are specified on the command line.
unlink('D', 'D-done', 'E', 'E-done');
unlink('A-1-done', 'A-2-done', 'A-3-done', 'B-1-done', 'B-2-done', 'B-3-done');
run_make_test(q!
A :: D; @#HELPER# -q out A-1 file A-1-done wait B-1-done out A-1-done
A ::; @#HELPER# -q out A-2 file A-2-done wait B-2-done out A-2-done
A ::; @#HELPER# -q out A-3 file A-3-done wait B-3-done out A-3-done
B :: E; @#HELPER# -q wait A-1-done out B-1 out B-1-done file B-1-done
B ::; @#HELPER# -q wait A-2-done out B-2 out B-2-done file B-2-done
B ::; @#HELPER# -q wait A-3-done out B-3 out B-3-done file B-3-done
D:; @#HELPER# -q out D file D wait E-done out D-done
E:; @#HELPER# -q wait D out E out E-done file E-done
.PHONY: D E
# This is just here so we don't fail with older versions of make
.WAIT:
!,
'-j10 A B', "D\nE\nE-done\nD-done\nA-1\nB-1\nB-1-done\nA-1-done\nA-2\nB-2\nB-2-done\nA-2-done\nA-3\nB-3\nB-3-done\nA-3-done\n");
# Wait for all double colon targets on the left, before building targets on the
# right.
# Double colon targets have reqular targets as prerequisites.
# Subtest 2.
# Run the same test with .WAIT and observe that all A recipes get started
# sequentially before the 1st B recipe gets started and then all B recipes get
# started sequentially.
# The targets are specified on the command line.
unlink('D', 'D-done', 'E', 'E-done');
unlink('A-1-done', 'A-2-done', 'A-3-done', 'B-1-done', 'B-2-done', 'B-3-done');
run_make_test(q!
A :: D; @#HELPER# -q out $@-1 out $@-1-done
A :: ; @#HELPER# -q out $@-2 out $@-2-done
A :: ; @#HELPER# -q out $@-3 out $@-3-done
B :: E; @#HELPER# -q out $@-1 out $@-1-done
B :: ; @#HELPER# -q out $@-2 out $@-2-done
B :: ; @#HELPER# -q out $@-3 out $@-3-done
D:; @#HELPER# -q out D out D-done
E:; @#HELPER# -q out E out E-done
.PHONY: D E
# This is just here so we don't fail with older versions of make
.WAIT:
!,
'-j10 A .WAIT B', "D\nD-done\nA-1\nA-1-done\nA-2\nA-2-done\nA-3\nA-3-done\nE\nE-done\nB-1\nB-1-done\nB-2\nB-2-done\nB-3\nB-3-done\n");
unlink('D', 'D-done', 'E', 'E-done');
unlink('A-1-done', 'A-2-done', 'A-3-done', 'B-1-done', 'B-2-done', 'B-3-done');
[SV 13862] Implement the .WAIT special target The next version of the POSIX standard defines parallel execution and requires the .WAIT special target as is implemented in some other versions of make. This implementation behaves similarly to others in that it does not create a relationship between targets in the dependency graph, so that the same two targets may be run in parallel if they appear as prerequisites elsewhere without .WAIT between them. Now that we support .WAIT it's trivial to also support prerequisites of the .NOTPARALLEL special target, which forces the prerequisites of those targets to be run serially (as if .WAIT was specified between each one). * NEWS: Announce the new .WAIT and .NOTPARALLEL support. * doc/make.texi (Parallel Disable): A new section to discuss ways in which parallel execution can be controlled. Modify cross-refs to refer to this section. * src/dep.h (struct dep): Add a new wait_here boolean. (parse_file_seq): Add PARSEFS_WAIT to check for .WAIT dependencies. * src/file.c (split_prereqs): Use PARSEFS_WAIT. (snap_deps): If .NOTPARALLEL has prerequisites, set .WAIT between each of _their_ prerequisites. (print_prereqs): Add back in .WAIT when printing prerequisites. * src/implicit.c (struct patdeps): Preserve wait_here. (pattern_search): Ditto. Use PARSEFS_WAIT when parsing prereqs for pattern rule expansion. * src/read.c (check_specials): Don't give up early: remembering to update these options is not worth the rare speedup. (check_special_file): If .WAIT is given as a target show an error-- once--if it has prereqs or commands. (record_files): Call check_special_file on each target. (parse_file_seq): If PARSEFS_WAIT is given, look for .WAIT prereqs. If we see one assume that we are building a struct dep chain and set the wait_here option while not putting it into the list. * src/remake.c (update_file_1): If wait_here is set and we are still running, then stop trying to build this target's prerequisites. * src/rule.c (get_rule_defn): Add .WAIT to the prerequisite list. * src/shuffle.c (shuffle_deps): Don't shuffle the prerequisite list if .WAIT appears anywhere in it. * tests/scripts/targets/WAIT: Add a test suite for this feature.
2022-09-13 06:18:49 +08:00
# This tells the test driver that the perl test script executed properly.
1;