264 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			Perl
		
	
	
	
			
		
		
	
	
			264 lines
		
	
	
		
			8.1 KiB
		
	
	
	
		
			Perl
		
	
	
	
| #
 | |
| #//===----------------------------------------------------------------------===//
 | |
| #//
 | |
| #// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
 | |
| #// See https://llvm.org/LICENSE.txt for license information.
 | |
| #// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
 | |
| #//
 | |
| #//===----------------------------------------------------------------------===//
 | |
| #
 | |
| 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;
 |