Radix cross Linux Build System

Cross-platform build system is designed to build distributions of different operating systems for a set of target devices

39 Commits   2 Branches   2 Tags
#!/bin/env perl

use FindBin;
use lib $FindBin::Bin;

use strict;
use warnings FATAL => 'all';

use File::Basename;
use File::Temp;
use _kxLab;


#
# Install file(s)
#
# usage:
#   $0 [options] source[ source] destination hardware
#
# where:
#        'source' - the list of source files to be installed into dest directory
#   'destination' - is a destination directory for installation all source files
#      'hardware' - is a HARDWARE variant
#
# options:
#   --preserve-source-dir=true  - preserve source directory tree in the dest dir,
#                                 for example, if source is foo/bar/file then we
#                                 will have destination such as  dest/foo/bar/file.
#
#   --preserve-source-dir=one   - preserve source directory depth is only 1. Its
#                                 mean that if we have source like foo/bar/file,
#                                 then destination will be dest/bar/file.
#

# Global variables
my $header_printed = 0;

my $cleanup = $ENV{DO_CREATE_DIST_FILES} ? 0 : 1;
my ($tempfd, $tempname);

sub usage
{
  print <<EOF;

Usage: install_targets [options] source[ source]
Options:
   --preserve-source-dir={true|one} - preserve source directory tree in the DEST dir.
                                      true: If source is foo/bar/file then destination
                                            file will be DEST/foo/bar/file.
                                       one: depth is only one directory. If source is
                                            fo/bar/file then destination will be
                                            DEST/bar/file.
   --destination=DEST               - where DEST is a destination directory.
   --toolchain=TOOLCHAIN            - where TOOLCHAIN ia a toolchain name;
   --hardware=HARDWARE              - where HARDWARE ia a HARDWARE name;
   --flavour=FLAVOUR                - where FLAVOUR ia a FLAVOUR name.

EOF
  exit;
}


# cleanpath( path )
sub cleanpath
{
  my $path = shift;
  $path =~ s!/{2,}!/!g;
  return $path;
}

# dist( file )
sub dist
{
  my $file = cleanpath(shift);
  $file =~ s!^.*dist/!!;
  print $tempfd "$file\n";
}

# newer_than( file1, file2 )
sub newer_than
{
  my $file1 = shift;
  my $file2 = shift;
  _kxLab::error( "install_targets: Source file missing: $file1" ) if ( ! -f $file1 );
  return( ! -f $file2 or -M $file1 < -M $file2 );
}

sub dir_is_empty
{
  my ($path) = @_;
  opendir DIR, $path;
  while( my $entry = readdir DIR )
  {
    next if( $entry =~ /^\.\.?$/ );
    closedir DIR;
    return 0;
  }
  closedir DIR;
  return 1;
}

# install_tree( install_dir, file, target, verbose )
sub install_tree
{
  my $install_dir = cleanpath(shift);
  my $file = shift;
  my $target = shift;
  my $verbose = shift;

  opendir(DIR, "$target");
  my @files = readdir(DIR);
  closedir DIR;
  foreach my $f ( @files )
  {
    next if ($f eq "." or $f eq "..");
    if( -d "$target/$f" )
    {
      install_tree( "$install_dir/$f", "$file/$f", "$target/$f", $verbose );
    }
    elsif( newer_than( "$target/$f", "$install_dir/$f" ) )
    {
      if( !$header_printed )
      {
        print "\n======= Installing files =======\n";
        $header_printed = 1;
      }
      print "Installing $f in $install_dir\n" if ( $verbose );
      _kxLab::system( "mkdir -p \"$install_dir\"" );
      _kxLab::system( "cp -fa \"$target/$f\" \"$install_dir\"" );
      dist( "$install_dir/$f" );
    }
  }
}




# install( install_dir, preserve_source_dir, verbose, targets )
sub install
{
  my $install_dir = cleanpath(shift);
  my $preserve_source_dir = shift;
  my $verbose = shift;
  my $targets = shift;

  foreach my $target ( @{$targets} )
  {
    my $file = basename($target);
    my $path = "";
    if( $preserve_source_dir eq "true" )
    {
      $path = dirname( $target );
    }
    elsif( $preserve_source_dir eq "one" )
    {
      $path = dirname( $target );
      $path = basename( $path );
    }
    elsif( $preserve_source_dir eq "two" )
    {
      my ($first, $second);

      $path = dirname( $target );
      $second = basename( $path );
      $path = dirname( $path );
      $first = basename( $path );
      $path = $first . "/" . $second;
    }

    if( -d $target )
    {
      if( dir_is_empty( $target ) )
      {
        _kxLab::system( "mkdir -p \"$install_dir/$path/$file\"" );
        dist( "$install_dir/$path/$file" );
      }
      else
      {
        install_tree( "$install_dir/$path/$file", "$file", "$target", $verbose );
      }
    }
    elsif( newer_than( $target, "$install_dir/$path/$file" ) )
    {
      if( !$header_printed )
      {
        print "\n======= Installing files =======\n" if ( $verbose );
        $header_printed = 1;
      }
      print "Installing $file in $install_dir/$path\n" if ( $verbose );
      _kxLab::system( "mkdir -p \"$install_dir/$path\"" );
      _kxLab::system( "cp -fa \"$target\" \"$install_dir/$path\"" );
      dist( "$install_dir/$path/$file" );
    }
  }
}

my $preserve_source_dir = "";
my $dest_dir;
my ($toolchain, $hardware, $flavour);
my $target_build_dir;
my @targets;
my $verbose = $ENV{VERBOSE};
my $curdir  = $ENV{CWD};
my $fname = "";


foreach ( @ARGV )
{
  if( /--preserve-source-dir=(\S*)/ )
  {
    $preserve_source_dir = $1;
  }
  elsif( /--destination=(\S*)/ )
  {
    $dest_dir = $1;
  }
  elsif( /--toolchain=(\S*)/ )
  {
    $toolchain = $1;
  }
  elsif( /--hardware=(\S*)/ )
  {
    $hardware = $1;
  }
  elsif( /--flavour=(\S*)/ )
  {
    $flavour = $1;
  }
  elsif( /--help/ )
  {
    usage;
  }
  elsif( /--/ )
  {
    while( <STDIN> )
    {
      #
      # NOTE: arguments from STDIN should be splitted by '\n'
      #
      my $arg = $_;

      chomp $arg;  $arg =~ s/\\040/ /g;

      push @targets, $arg;
    }

    last;
  }
  else
  {
    my $arg = $_;

    chomp $arg; $arg =~ s/\\040/ /g;

    push @targets, $arg;
  }
}

if( ! defined $dest_dir  or $dest_dir eq "" )  { usage; }
if( ! defined $toolchain or $toolchain eq "" ) { usage; }
if( ! defined $hardware  or $hardware eq "" )  { usage; }
if( ! defined $flavour   or $flavour eq "" )
{
  $flavour = "";
  $target_build_dir = "." . $toolchain . "/" . $hardware;
}
else
{
  $target_build_dir = "." . $toolchain . "/" . $hardware . "/" . $flavour;
}

if ( $curdir )
{
  $fname = "$curdir/" . $target_build_dir . "/.dist.XXXXXX";
}
else
{
  $fname = $target_build_dir . "/.dist.XXXXXX";
}

($tempfd, $tempname) = File::Temp::tempfile( $fname, UNLINK => $cleanup );

install( $dest_dir, $preserve_source_dir, $verbose, \@targets );