eval 'exec "$PERL" -Sw "$0" "$@"' if 0; #************************************************************** # # Licensed to the Apache Software Foundation (ASF) under one # or more contributor license agreements. See the NOTICE file # distributed with this work for additional information # regarding copyright ownership. The ASF licenses this file # to you under the Apache License, Version 2.0 (the # "License"); you may not use this file except in compliance # with the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, # software distributed under the License is distributed on an # "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY # KIND, either express or implied. See the License for the # specific language governing permissions and limitations # under the License. # #************************************************************** use lib("$ENV{SOLARENV}/bin/modules"); use SourceConfig; my $keep_going = 0; my $dry_run = 0; my $max_running = 1; while (@ARGV) { my $arg = shift(@ARGV); if ($arg =~ /^-P([1-9]\d*)$/) { $max_running = $1; } elsif ($arg eq '--') { last; } else { my $n = substr($arg, 0, 1) eq '-' ? 1 : 0; while ($n && $n < length($arg)) { my $c = substr($arg, $n++, 1); if ($c eq 'k') { $keep_going = 1; } elsif ($c eq 'n') { $dry_run = 1; } else { $n = 0; last; } } if (!$n) { print STDERR "unknown argument \"$arg\"\n"; print STDERR "usage: $0 [-kn] [-P] [-- ]\n"; print STDERR " -k continue with other dmake invocations upon\n"; print STDERR " failure\n"; print STDERR " -n write directories that would be processed\n"; print STDERR " to standard output\n"; print STDERR " -P number of parallel dmake invocations\n"; print STDERR " are passed to dmake invocations\n"; exit(1); } } } my @testpaths = (); my $sc = SourceConfig->new($ENV{'SOLARSRC'}); my $module; my $gbuildpath = "$ENV{'SOLARSRC'}/GNUmakefile"; foreach $module ($sc->get_active_modules()) { my $buildlst = $sc->get_module_build_list($module); next unless defined($buildlst); my %deps = (); open(BUILDLST, $buildlst) or die("cannot open $buildlst"); while () { next unless /^\s*\w+\s+(\S+)\s+nmake\s+-\s+all\s+(\S+)(\s+(:?\S+\s+)*)NULL\s*$/; my ($dir, $id, $ids) = ($1, $2, $3); $dir =~ s|\\|/|g; $dir =~ s|^[^/]+||; my $path = $sc->get_module_path($module) . $dir; my $makefile = $path . '/makefile.mk'; open(MAKEFILE, $makefile) or die("cannot open $makefile"); while () { if (/\bOOO_SUBSEQUENT_TESTS\b/) { push(@testpaths, $path); $deps{$id} = $ids; last; } } close(MAKEFILE); } close(BUILDLST); my $id1; foreach $id1 (keys(%deps)) { my ($id2, $ids); while (($id2, $ids) = each(%deps)) { $ids !~ /\s\Q$id1\E\s/ or die("$module: $id2 depends on $id1"); } } } if ($dry_run) { foreach $path (@testpaths) { print "$path\n"; } print "$gbuildpath\n"; exit(0); } my @failedpaths = (); my @gbuildargs = ("-j$max_running", "-s", "-r"); if ($keep_going) { push(@gbuildargs,"-k"); } push(@gbuildargs, "--file=$gbuildpath"); push(@gbuildargs, "subsequentcheck"); if (system($ENV{'GNUMAKE'}, @gbuildargs) != 0) { push(@failedpaths,$gbuildpath); @testpaths = () unless $keep_going; } my $cmd = 'dmake'; foreach (@ARGV) { s/'/'\''/g; $cmd .= " '" . $_ . "'"; } $cmd .= ' 2>&1 |'; my %pids = (); my $running = 0; my $counter = 0; while (@testpaths || $running > 0) { while (@testpaths && $running < $max_running) { my $testpath = shift(@testpaths); ++$counter; print("$counter: make $testpath\n"); my $pid = fork(); defined($pid) or die("$counter: $!"); if ($pid == 0) { chdir($testpath) or die("$counter: $!"); $ENV{'OOO_SUBSEQUENT_TESTS'} = 'TRUE'; open(OUTPUT, $cmd) or die("$counter: $!"); while () { s/\r?\n$//; print("$counter: $_\n"); } close(OUTPUT); exit($? == 0 ? 0 : 1); } $pids{$pid} = $testpath; ++$running; } my $pid = wait(); $pid != -1 or die($!); my $testpath = delete($pids{$pid}); defined($testpath) or die("unmatched PID $pid"); if ($? != 0) { push(@failedpaths, $testpath); @testpaths = () unless $keep_going; } --$running; } my $failedpath; foreach $failedpath (@failedpaths) { print STDERR "failed in $failedpath\n"; } exit(scalar(@failedpaths) == 0 ? 0 : 1);