# -*-perl-*- $description = "Test --output-sync (-O) option."; $details = "Test the synchronization of output from parallel jobs."; # If we don't have output sync support, never mind. exists $FEATURES{'output-sync'} or return -1; # Output sync can't be tested without parallelization $parallel_jobs or return -1; if ($vos) { $sleep_command = "sleep -seconds"; } else { $sleep_command = "sleep"; } # The following subdirectories with Makefiles are used in several # of the following tests. The model is: # foo/Makefile - has a "foo" target that waits for the bar target # bar/Makefile - has a "bar" target that runs immediately # - has a "baz" target that waits for the foo target # # So, you start the two sub-makes in parallel and first the "bar" target is # built, followed by "foo", followed by "baz". The trick is that first each # target prints a "start" statement, then waits (if appropriate), then prints # an end statement. Thus we can tell if the -O flag is working, since # otherwise these statements would be mixed together. @syncfiles = (); sub output_sync_clean { rmfiles('foo/Makefile', 'bar/Makefile', @syncfiles); rmdir('foo'); rmdir('bar'); } # We synchronize the different jobs by having them wait for a sentinel file to # be created, instead of relying on a certain amount of time passing. # Unfortunately in this test we have to sleep after we see the sync file, # since we also want to make the obtaining of the write synchronization lock # reliable. If things are too fast, then sometimes a different job will steal # the output sync lock and the output is mis-ordered from what we expect. sub output_sync_wait { return "while [ ! -f ../mksync.$_[0] ]; do :; done; rm -f ../mksync.$_[0].wait; $sleep_command 1"; } sub output_sync_set { return "date > ../mksync.$_[0]"; } @syncfiles = qw(mksync.foo mksync.foo_start mksync.bar mksync.bar_start); output_sync_clean(); mkdir('foo', 0777); mkdir('bar', 0777); $set_foo = output_sync_set('foo'); $set_bar = output_sync_set('bar'); $set_foo_start = output_sync_set('foo_start'); $set_bar_start = output_sync_set('bar_start'); $wait_foo = output_sync_wait('foo'); $wait_bar = output_sync_wait('bar'); $wait_foo_start = output_sync_set('foo_start'); $wait_bar_start = output_sync_set('bar_start'); open(MAKEFILE,"> foo/Makefile"); print MAKEFILE < bar/Makefile"); print MAKEFILE <&2) !, '-w -Oline', "#MAKE#: Entering directory '#PWD#'\nfoo\n#MAKE#: Leaving directory '#PWD#'\n"); # Ensure that output generated while parsing makefiles is synced # when appropriate. run_make_test(q! $(shell echo foo 1>&2) all: ; echo bar !, '-s -w -Otarget', "#MAKE#: Entering directory '#PWD#'\nfoo\n#MAKE#: Leaving directory '#PWD#'\n#MAKE#: Entering directory '#PWD#'\nbar\n#MAKE#: Leaving directory '#PWD#'\n"); # Test recursion $m1 = get_tmpfile(); $m2 = get_tmpfile(); open(M1, "> $m1"); print M1 <<'EOF'; $(shell echo d1 stderr 1>&2) $(info d1 stdout) all:; @: EOF close(M1); open(M2, "> $m2"); print M2 <<'EOF'; $(shell echo d2 stderr 1>&2) $(info d2 stdout) all:; @: # Force an ordering on the output $(shell sleep 1) EOF close(M2); run_make_test(qq! all: t1 t2 t1: ; \@\$(MAKE) -f $m1 t2: ; \@\$(MAKE) -f $m2 !, "-j -Oline", "#MAKE#[1]: Entering directory '#PWD#'\nd1 stderr\nd1 stdout\n#MAKE#[1]: Leaving directory '#PWD#'\n#MAKE#[1]: Entering directory '#PWD#'\nd2 stderr\nd2 stdout\n#MAKE#[1]: Leaving directory '#PWD#'\n"); rmfiles($m1, $m2); # Ensure that output generated while parsing makefiles is synced # when appropriate. $m1 = get_tmpfile(); open(M1, "> $m1"); print M1 <<'EOF'; $(shell echo d1 stderr 1>&2) $(info d1 stdout) $(error d1 failed) all:; @: EOF close(M1); run_make_test(qq! all: t1 t1: ; -\@\$(MAKE) -f $m1 !, "-j -Oline", "#MAKE#[1]: Entering directory '#PWD#'\nd1 stderr\nd1 stdout\n$m1:3: *** d1 failed. Stop.\n#MAKE#[1]: Leaving directory '#PWD#'\n#MAKEFILE#:3: recipe for target 't1' failed\n#MAKE#: [t1] Error 2 (ignored)\n"); rmfiles($m1); # Test $(error ...) functions in recipes run_make_test(q! foo: $(OBJS) ; echo $(or $(filter %.o,$^),$(error fail)) !, '-O', "#MAKEFILE#:2: *** fail. Stop.\n", 512); # This tells the test driver that the perl test script executed properly. 1;