diff options
Diffstat (limited to 'final/runtime/tools/lib/Build.pm')
-rw-r--r-- | final/runtime/tools/lib/Build.pm | 264 |
1 files changed, 264 insertions, 0 deletions
diff --git a/final/runtime/tools/lib/Build.pm b/final/runtime/tools/lib/Build.pm new file mode 100644 index 0000000..cf67156 --- /dev/null +++ b/final/runtime/tools/lib/Build.pm @@ -0,0 +1,264 @@ +# +#//===----------------------------------------------------------------------===// +#// +#// The LLVM Compiler Infrastructure +#// +#// This file is dual licensed under the MIT and the University of Illinois Open +#// Source Licenses. See LICENSE.txt for details. +#// +#//===----------------------------------------------------------------------===// +# +package Build; + +use strict; +use warnings; + +use Cwd qw{}; + +use LibOMP; +use tools; +use Uname; +use Platform ":vars"; + +my $host = Uname::host_name(); +my $root = $ENV{ LIBOMP_WORK }; +my $tmp = $ENV{ LIBOMP_TMP }; +my $out = $ENV{ LIBOMP_EXPORTS }; + +my @jobs; +our $start = time(); + +# -------------------------------------------------------------------------------------------------- +# Helper functions. +# -------------------------------------------------------------------------------------------------- + +# tstr -- Time string. Returns string "yyyy-dd-mm hh:mm:ss UTC". +sub tstr(;$) { + my ( $time ) = @_; + if ( not defined( $time ) ) { + $time = time(); + }; # if + my ( $sec, $min, $hour, $day, $month, $year ) = gmtime( $time ); + $month += 1; + $year += 1900; + my $str = sprintf( "%04d-%02d-%02d %02d:%02d:%02d UTC", $year, $month, $day, $hour, $min, $sec ); + return $str; +}; # sub tstr + +# dstr -- Duration string. Returns string "hh:mm:ss". +sub dstr($) { + # Get time in seconds and format it as time in hours, minutes, seconds. + my ( $sec ) = @_; + my ( $h, $m, $s ); + $h = int( $sec / 3600 ); + $sec = $sec - $h * 3600; + $m = int( $sec / 60 ); + $sec = $sec - $m * 60; + $s = int( $sec ); + $sec = $sec - $s; + return sprintf( "%02d:%02d:%02d", $h, $m, $s ); +}; # sub dstr + +# rstr -- Result string. +sub rstr($) { + my ( $rc ) = @_; + return ( $rc == 0 ? "+++ Success +++" : "--- Failure ---" ); +}; # sub rstr + +sub shorter($;$) { + # Return shorter variant of path -- either absolute or relative. + my ( $path, $base ) = @_; + my $abs = abs_path( $path ); + my $rel = rel_path( $path, $base ); + if ( $rel eq "" ) { + $rel = "."; + }; # if + $path = ( length( $rel ) < length( $abs ) ? $rel : $abs ); + if ( $target_os eq "win" ) { + $path =~ s{\\}{/}g; + }; # if + return $path; +}; # sub shorter + +sub tee($$) { + + my ( $action, $file ) = @_; + my $pid = 0; + + my $save_stdout = Symbol::gensym(); + my $save_stderr = Symbol::gensym(); + + # --- redirect stdout --- + STDOUT->flush(); + # Save stdout in $save_stdout. + open( $save_stdout, ">&" . STDOUT->fileno() ) + or die( "Cannot dup filehandle: $!; stopped" ); + # Redirect stdout to tee or to file. + if ( $tools::verbose ) { + $pid = open( STDOUT, "| tee -a \"$file\"" ) + or die "Cannot open pipe to \"tee\": $!; stopped"; + } else { + open( STDOUT, ">>$file" ) + or die "Cannot open file \"$file\" for writing: $!; stopped"; + }; # if + + # --- redirect stderr --- + STDERR->flush(); + # Save stderr in $save_stderr. + open( $save_stderr, ">&" . STDERR->fileno() ) + or die( "Cannot dup filehandle: $!; stopped" ); + # Redirect stderr to stdout. + open( STDERR, ">&" . STDOUT->fileno() ) + or die( "Cannot dup filehandle: $!; stopped" ); + + # Perform actions. + $action->(); + + # --- restore stderr --- + STDERR->flush(); + # Restore stderr from $save_stderr. + open( STDERR, ">&" . $save_stderr->fileno() ) + or die( "Cannot dup filehandle: $!; stopped" ); + # Close $save_stderr. + $save_stderr->close() or die ( "Cannot close filehandle: $!; stopped" ); + + # --- restore stdout --- + STDOUT->flush(); + # Restore stdout from $save_stdout. + open( STDOUT, ">&" . $save_stdout->fileno() ) + or die( "Cannot dup filehandle: $!; stopped" ); + # Close $save_stdout. + $save_stdout->close() or die ( "Cannot close filehandle: $!; stopped" ); + + # Wait for the child tee process, otherwise output of make and build.pl interleaves. + if ( $pid != 0 ) { + waitpid( $pid, 0 ); + }; # if + +}; # sub tee + +sub log_it($$@) { + my ( $title, $format, @args ) = @_; + my $message = sprintf( $format, @args ); + my $progress = cat_file( $tmp, sprintf( "%s-%s.log", $target_platform, Uname::host_name() ) ); + if ( $title ne "" and $message ne "" ) { + my $line = sprintf( "%-15s : %s\n", $title, $message ); + info( $line ); + write_file( $progress, tstr() . ": " . $line, -append => 1 ); + } else { + write_file( $progress, "\n", -append => 1 ); + }; # if +}; # sub log_it + +sub progress($$@) { + my ( $title, $format, @args ) = @_; + log_it( $title, $format, @args ); +}; # sub progress + +sub summary() { + my $total = @jobs; + my $success = 0; + my $finish = time(); + foreach my $job ( @jobs ) { + my ( $build_dir, $rc ) = ( $job->{ build_dir }, $job->{ rc } ); + progress( rstr( $rc ), "%s", $build_dir ); + if ( $rc == 0 ) { + ++ $success; + }; # if + }; # foreach $job + my $failure = $total - $success; + progress( "Successes", "%3d of %3d", $success, $total ); + progress( "Failures", "%3d of %3d", $failure, $total ); + progress( "Time elapsed", " %s", dstr( $finish - $start ) ); + progress( "Overall result", "%s", rstr( $failure ) ); + return $failure; +}; # sub summary + +# -------------------------------------------------------------------------------------------------- +# Worker functions. +# -------------------------------------------------------------------------------------------------- + +sub init() { + make_dir( $tmp ); +}; # sub init + +sub clean(@) { + # Clean directories. + my ( @dirs ) = @_; + my $exit = 0; + # Mimisc makefile -- print a command. + print( "rm -f -r " . join( " ", map( shorter( $_ ) . "/*", @dirs ) ) . "\n" ); + $exit = + execute( + [ $^X, cat_file( $ENV{ LIBOMP_WORK }, "tools", "clean-dir.pl" ), @dirs ], + -ignore_status => 1, + ( $tools::verbose ? () : ( -stdout => undef, -stderr => "" ) ), + ); + return $exit; +}; # sub clean + +sub make($$$) { + # Change dir to build one and run make. + my ( $job, $clean, $marker ) = @_; + my $dir = $job->{ build_dir }; + my $makefile = $job->{ makefile }; + my $args = $job->{ make_args }; + my $cwd = Cwd::cwd(); + my $width = -10; + + my $exit; + $dir = cat_dir( $tmp, $dir ); + make_dir( $dir ); + change_dir( $dir ); + + my $actions = + sub { + my $start = time(); + $makefile = shorter( $makefile ); + print( "-" x 79, "\n" ); + printf( "%${width}s: %s\n", "Started", tstr( $start ) ); + printf( "%${width}s: %s\n", "Root dir", $root ); + printf( "%${width}s: %s\n", "Build dir", shorter( $dir, $root ) ); + printf( "%${width}s: %s\n", "Makefile", $makefile ); + print( "-" x 79, "\n" ); + { + # Use shorter LIBOMP_WORK to have shorter command lines. + # Note: Some tools may not work if current dir is changed. + local $ENV{ LIBOMP_WORK } = shorter( $ENV{ LIBOMP_WORK } ); + $exit = + execute( + [ + "make", + "-r", + "-f", $makefile, + "arch=" . $target_arch, + "marker=$marker", + @$args + ], + -ignore_status => 1 + ); + if ( $clean and $exit == 0 ) { + $exit = clean( $dir ); + }; # if + } + my $finish = time(); + print( "-" x 79, "\n" ); + printf( "%${width}s: %s\n", "Finished", tstr( $finish ) ); + printf( "%${width}s: %s\n", "Elapsed", dstr( $finish - $start ) ); + printf( "%${width}s: %s\n", "Result", rstr( $exit ) ); + print( "-" x 79, "\n" ); + print( "\n" ); + }; # sub + tee( $actions, "build.log" ); + + change_dir( $cwd ); + + # Save completed job to be able print summary later. + $job->{ rc } = $exit; + push( @jobs, $job ); + + return $exit; + +}; # sub make + +1; |