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

#
# Generate .REQUIRES file for package.
#
# usage:
#   $0 [options] dir dir outfile
#
# where: 'dir'     - is directory where made required package
#        'outfile' - output file with following format:
#
# _kxLibc=1.0.7
# pkgtool=0.0.1
#
# empty version is allowed:
#
# pkg=
#

my ($toolchain, $hardware, $flavour);

sub read_requires
{
  my %requires;
  my ( $name, $version, $group );

  my ( $file_name, $makefile );

  my $ptype = shift;

  if( $ptype eq "bin" )
  {
    $name    = "BIN_PKG_NAME";
    $version = "BIN_PKG_VERSION";
    $group   = "BIN_PKG_GROUP";
  }
  elsif( $ptype eq "dev" )
  {
    $name    = "DEV_PKG_NAME";
    $version = "DEV_PKG_VERSION";
    $group   = "DEV_PKG_GROUP";
  }
  else
  {
    $name    = "PKG_NAME";
    $version = "PKG_VERSION";
    $group   = "PKG_GROUP";
  }


  foreach my $req ( reverse @_ )
  {
    my $d = `echo $req | cut -f 1 -d '^'`;
    $d =~ s/^\s+|\s+$//;

    $file_name = "${top_build_dir}/$d/Makefile";
    $makefile = `cat $file_name`;
    if( $makefile =~ m/^ *([_A-Za-z]*[_A-Za-z0-9]*)$name(.+= +)(.+)/gm )
    {
      my ( @p, @n, @v );
      my ( $n, $v, $g );

      my $prefix = $1;

      my $cdir = "${top_build_dir}/$d";
      my $shell_output = <<`SHELL`;
cd $cdir
make TOOLCHAIN=$toolchain HARDWARE=$hardware FLAVOUR=$flavour -f $file_name print-$prefix$name 2>/dev/null
exit 0
SHELL
      while( $shell_output =~ m/^ *$prefix$name(.+= +)(.+)/gm ) { $n = $2; }

      $shell_output = <<`SHELL`;
cd $cdir
make TOOLCHAIN=$toolchain HARDWARE=$hardware FLAVOUR=$flavour -f $file_name print-$prefix$version 2>/dev/null
exit 0
SHELL
      while( $shell_output =~ m/^ *$prefix$version(.+= +)(.+)/gm ) { $v = $2; }

      $shell_output = <<`SHELL`;
cd $cdir
make TOOLCHAIN=$toolchain HARDWARE=$hardware FLAVOUR=$flavour -f $file_name print-$prefix$group 2>/dev/null
exit 0
SHELL
      while( $shell_output =~ m/^ *$prefix$group(.+= +)(.+)/gm ) { $g = $2; }

      $requires{"$d"} = \@p;
      if( $g ) { @n = split / +/, $g . '/' . $n; }
      else     { @n = split / +/, $n; }
      push( @{ $requires{"$d"} }, @n );
      @v = split / +/, $v;
      if( $requires{"$d"} )
      {
        push( @{ $requires{"$d"} }, @v );
      }
    }
    else
    {
      #
      # The ..._PKG_NAME is not found in a Makefile then
      # assume that this Makefile is a collection (depth=1):
      # ---------------------------------------------------
      # NOTE:
      # ----
      #   We do not allow flavours in the package .REQUIRES file.
      #
      my $cdir = "${top_build_dir}/$d";
      #
      # We read the head of Makefile until '__END_OF_REQUIRES__' keyword.
      # The 'build-system/constants.mk' should be included before requires.
      #
      my $requires_output = <<`SHELL`;
cd $cdir
head -n `cat Makefile | grep -n "__END_OF_REQUIRES__" | cut -f 1 -d ':'` Makefile | \
  make TOOLCHAIN=$toolchain HARDWARE=$hardware FLAVOUR=$flavour -f - -p __build_requires__ 2>/dev/null | grep "REQUIRES"
exit 0
SHELL

      while( $requires_output =~ m/^REQUIRES(.+= +)(.+)/gm )
      {
        my @r = split( " ", $2 );
        foreach my $req ( reverse @r )
        {
          $d = `echo $req | cut -f 1 -d '^'`;
          $d =~ s/^\s+|\s+$//;

          $file_name = "${top_build_dir}/$d/Makefile";
          $makefile = `cat $file_name`;
          if( $makefile =~ m/^ *([_A-Za-z]*[_A-Za-z0-9]*)$name(.+= +)(.+)/gm )
          {
            my ( @p, @n, @v );
            my ( $n, $v, $g );

            my $prefix = $1;

            my $cdir = "${top_build_dir}/$d";
            my $shell_output = <<`SHELL`;
cd $cdir
make TOOLCHAIN=$toolchain HARDWARE=$hardware FLAVOUR=$flavour -f $file_name print-$prefix$name 2>/dev/null
exit 0
SHELL
            while( $shell_output =~ m/^ *$prefix$name(.+= +)(.+)/gm ) { $n = $2; }

            $shell_output = <<`SHELL`;
cd $cdir
make TOOLCHAIN=$toolchain HARDWARE=$hardware FLAVOUR=$flavour -f $file_name print-$prefix$version 2>/dev/null
exit 0
SHELL
            while( $shell_output =~ m/^ *$prefix$version(.+= +)(.+)/gm ) { $v = $2; }

            $shell_output = <<`SHELL`;
cd $cdir
make TOOLCHAIN=$toolchain HARDWARE=$hardware FLAVOUR=$flavour -f $file_name print-$prefix$group 2>/dev/null
exit 0
SHELL
            while( $shell_output =~ m/^ *$prefix$group(.+= +)(.+)/gm ) { $g = $2; }

            $requires{"$d"} = \@p;
            if( $g ) { @n = split / +/, $g . '/' . $n; }
            else     { @n = split / +/, $n; }
            push( @{ $requires{"$d"} }, @n );
            @v = split / +/, $v;
            if( $requires{"$d"} )
            {
              push( @{ $requires{"$d"} }, @v );
            }
          }

        } # end of foreach ( req )

      } # End of while ( shell_output )

    }

  }

  return %requires;
}

sub usage
{
  print <<EOF;

Usage: build_pkg_requires [options] dir ... dir output_file_name
Options:
   --toolchain={TOOLCHAIN}  - actual Toolchain name;
   --hardware={HARDVARE}    - actual  Hardware name;
   --flavour={FLAVOUR}      - actual   Flavour name;
   --pkg-type={all|bin|dev} - find required packages of defined type only;
   --all                    - find required packages of all types;
   --bin                    - find binary packages only;
   --dev                    - find development packages only.

EOF
  exit;
}


my $pkg_type;

my @dirs;

foreach ( @ARGV )
{
  if( /--toolchain=(\S*)/ )
  {
    $toolchain = $1;
  }
  elsif( /--hardware=(\S*)/ )
  {
    $hardware = $1;
  }
  elsif( /--flavour=(\S*)/ )
  {
    $flavour = $1;
  }
  elsif( /--pkg-type=(\S*)/ )
  {
    $pkg_type = $1;
  }
  elsif( /--all/ )
  {
    $pkg_type = "all";
  }
  elsif( /--bin/ )
  {
    $pkg_type = "bin";
  }
  elsif( /--dev/ )
  {
    $pkg_type = "dev";
  }
  elsif( /--help/ )
  {
    usage;
  }
  else
  {
    push @dirs, $_;
  }
}

$reqfile = pop @dirs;

if( $pkg_type eq "" ) { $pkg_type = "all"; }

# Set up $top_build_dir
$pwd = `pwd`;
chomp $pwd;

if( $ENV{TOP_BUILD_DIR_ABS} eq "" )
{
  $p = $pwd;
  while( ! -f "$p/build-system/core.mk" )
  {
    $p =~ m!(.*)/(.*)!;
    $p = $1;
  }
  $top_build_dir = $p;
}
else
{
  $top_build_dir = $ENV{TOP_BUILD_DIR_ABS};
}

# Open the output file
open( REQUIRES_FILE, "> $reqfile" );


# Read package names and versions from required Makefiles
%requires = read_requires( $pkg_type, @dirs );

while( ($pkg, $nv) = each %requires )
{
   print REQUIRES_FILE "${$nv}[0]=${$nv}[1]\n";
}


# Close output file
close REQUIRES_FILE;