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
     5         kx #!/bin/env perl
     5         kx 
     5         kx use FindBin;
     5         kx use lib $FindBin::Bin;
     5         kx 
     5         kx use strict;
     5         kx use warnings FATAL => 'all';
     5         kx 
     5         kx use IO::Handle;
     5         kx use File::Basename;
     5         kx use File::Temp;
     5         kx 
     5         kx use List::MoreUtils qw(uniq);
     5         kx use Data::Dumper qw(Dumper);
     5         kx 
     5         kx use _kxLab;
     5         kx 
     5         kx #
     5         kx # Generate $(HARDWARE).pkglist file for current directory
     5         kx #
     5         kx # usage:
     5         kx #   $0 format topdir toolchain hardware [flavour]
     5         kx #
     5         kx # where:
     5         kx #      'format' - the output format: list or tree
     5         kx #      'topdir' - is a absolute path to the top directory of checked out branch
     5         kx #   'toolchain' - is a TOOLCHAIN name
     5         kx #    'hardware' - is a HARDWARE variant
     5         kx #     'flavour' - is a FLAVOUR variant
     5         kx #
     5         kx 
     5         kx # global variables
     5         kx my ($build_system);
     5         kx my ($format, $topdir, $toolchain, $hardware, $flavour);
     5         kx my ($target_build_dir, $srclist_file);
     5         kx my ($system_version, $distro_name, $distro_version, $url);
     5         kx my @tarballs = ();
     5         kx 
     5         kx sub usage
     5         kx {
     5         kx   print <<EOF;
     5         kx 
     5         kx Usage: $0 format topdir toolchain hardware [flavour]
     5         kx Where:
     5         kx           format - the output format: list or tree
     5         kx           topdir - is a absolute path to the top of checked out branch;
     5         kx        toolchain - is a TOOLCHAIN name;
     5         kx         hardware - is a HARDWARE variant;
     5         kx          flavour - is a FLAVOUR variant.
     5         kx 
     5         kx EOF
     5         kx   exit;
     5         kx }
     5         kx 
     5         kx #
     5         kx # Getting information from build-system/constants.mk
     5         kx #
     5         kx sub system_version
     5         kx {
     5         kx   my $build_system = shift;
     5         kx   my $version;
     5         kx 
     5         kx   open( FILE, "< $build_system/constants.mk" );
     5         kx 
     5         kx   while( <FILE> )
     5         kx   {
     5         kx     if( /^SYSTEM_VERSION(.+= +)(.+)/ )
     5         kx     {
     5         kx       $version = $2;
     5         kx     }
     5         kx   }
     5         kx   close( FILE );
     5         kx 
     5         kx   return $version;
     5         kx }
     5         kx 
     5         kx sub distro_name
     5         kx {
     5         kx   my $build_system = shift;
     5         kx   my $name;
     5         kx 
     5         kx   open( FILE, "< $build_system/constants.mk" );
     5         kx 
     5         kx   while( <FILE> )
     5         kx   {
     5         kx     if( /^DISTRO_NAME(.+= +)(.+)/ )
     5         kx     {
     5         kx       $name = $2;
     5         kx     }
     5         kx   }
     5         kx   close( FILE );
     5         kx 
     5         kx   return $name;
     5         kx }
     5         kx 
     5         kx sub distro_version
     5         kx {
     5         kx   my $build_system = shift;
     5         kx   my $name;
     5         kx 
     5         kx   open( FILE, "< $build_system/constants.mk" );
     5         kx 
     5         kx   while( <FILE> )
     5         kx   {
     5         kx     if( /^DISTRO_VERSION(.+= +)(.+)/ )
     5         kx     {
     5         kx       $name = $2;
     5         kx     }
     5         kx   }
     5         kx   close( FILE );
     5         kx 
     5         kx   return $name;
     5         kx }
     5         kx 
     5         kx sub bug_url
     5         kx {
     5         kx   my $build_system = shift;
     5         kx   my $url;
     5         kx 
     5         kx   open( FILE, "< $build_system/constants.mk" );
     5         kx 
     5         kx   while( <FILE> )
     5         kx   {
     5         kx     if( /^BUG_URL(.+= +)(.+)/ )
     5         kx     {
     5         kx       $url = $2;
     5         kx     }
     5         kx   }
     5         kx   close( FILE );
     5         kx 
     5         kx   return $url;
     5         kx }
     5         kx 
     5         kx #
     5         kx # value_from_makefile( $makefile, $variable_name, $stop_line ):
     5         kx # ------------------------------------------------------------
     5         kx #   This function returns the value of variable defined in the
     5         kx #   Makefile on global level before od REQUIRES declaration.
     5         kx #
     5         kx #   The optional $stop_line argument presents the start of the
     5         kx #   line which terminates the analized part of Makefile.
     5         kx #
     5         kx sub value_from_makefile
     5         kx {
     5         kx   my $makefile  = shift;
     5         kx   my $vname     = shift;
     5         kx   my $stop_line = shift;
     5         kx   my $value     = "";
     5         kx 
     5         kx   if( !defined $stop_line || $stop_line eq '' )
     5         kx   {
     5         kx     $stop_line = "__END_OF_REQUIRES__";
     5         kx   }
     5         kx   else
     5         kx   {
     5         kx     $stop_line = "^" . $stop_line;
     5         kx   }
     5         kx 
     5         kx   my $cdir = dirname( $makefile );
     5         kx 
     5         kx   my $shell_output = <<`SHELL`;
     5         kx cd $cdir
     5         kx head -n `cat Makefile | grep -n "$stop_line" | cut -f 1 -d ':'` Makefile | \
     5         kx   make TOOLCHAIN=$toolchain HARDWARE=$hardware FLAVOUR=$flavour -f - -p __build_requires__ 2>/dev/null | grep "$vname"
     5         kx exit 0
     5         kx SHELL
     5         kx 
     5         kx   if( $shell_output =~ m/^$vname(.+= +)(.+)/gm )
     5         kx   {
     5         kx     $value = $2;
     5         kx   }
     5         kx 
     5         kx   return $value;
     5         kx }
     5         kx 
     5         kx #
     5         kx # Getting information from Makefile:
     5         kx #
     5         kx sub pkg_group
     5         kx {
     5         kx   my $makefile = shift;
     5         kx   my $group;
     5         kx 
     5         kx   open( FILE, '<', $makefile );
     5         kx 
     5         kx   while( <FILE> )
     5         kx   {
     5         kx     if( /^PKG_GROUP(.+= +)(.+)/ )
     5         kx     {
     5         kx       $group = $2;
     5         kx     }
     5         kx   }
     5         kx   close( FILE );
     5         kx 
     5         kx   return $group;
     5         kx }
     5         kx 
     5         kx sub pkg_name
     5         kx {
     5         kx   my $makefile = shift;
     5         kx   my $name = "";
     5         kx 
     5         kx   open( FILE, '<', $makefile );
     5         kx 
     5         kx   while( <FILE> )
     5         kx   {
     5         kx     if( /^[A-Z_0-9]*_PKG_NAME(.+= +)(.+)/ )
     5         kx     {
     5         kx       $name = $2;
     5         kx     }
     5         kx   }
     5         kx   close( FILE );
     5         kx 
     5         kx   return $name;
     5         kx }
     5         kx 
     5         kx sub pkg_version
     5         kx {
     5         kx   my $makefile = shift;
     5         kx   my $version;
     5         kx 
     5         kx   my $stop_line;
     5         kx 
     5         kx   open( FILE, '<', $makefile );
     5         kx 
     5         kx   while( <FILE> )
     5         kx   {
     5         kx     if( /^([A-Z_0-9]*_PKG_VERSION)(.+= +)(.+)/ )
     5         kx     {
     5         kx       $stop_line  = $1;
     5         kx       $version    = $3;
     5         kx     }
     5         kx   }
     5         kx   close( FILE );
     5         kx 
     5         kx   # check if version is present as a reference to some variable:
     5         kx   if( $version =~ m/^\$\((.+)\)/ )
     5         kx   {
     5         kx     my $vname = $1;
     5         kx 
     5         kx     # get value of referenced variable
     5         kx     $version = value_from_makefile( $makefile, $vname, $stop_line );
     5         kx   }
     5         kx 
     5         kx   return $version;
     5         kx }
     5         kx 
     5         kx #
     5         kx # Getting information from .requires and .dist files:
     5         kx #
     5         kx sub built_gcc_libs
     5         kx {
     5         kx   my $makefile = shift;
     5         kx   my $stop_line;
     5         kx   my $vname = $hardware;
     5         kx   my $libs;
     5         kx 
     5         kx   $vname =~ tr/a-z-/A-Z_/;
     5         kx   $vname .= "_USE_BUILT_GCC_LIBS";
     5         kx 
     5         kx   $libs = value_from_makefile( $makefile, $vname, $stop_line );
     5         kx 
     5         kx   return $libs;
     5         kx }
     5         kx 
     5         kx sub get_root
     5         kx {
     5         kx   my $requires = $target_build_dir . "/.requires";
     5         kx   my $root = "";
     5         kx 
     5         kx   if( -f $requires )
     5         kx   {
     5         kx     open( FILE, '<', $requires ) or
     5         kx       _kxLab::error( "$0: Could not open $requires file: $!" );
     5         kx     while( <FILE> )
     5         kx     {
     5         kx       if( /^# ROOT(=)(.+)/ )
     5         kx       {
     5         kx         $root = $2;
     5         kx       }
     5         kx     }
     5         kx     close FILE;
     5         kx   }
     5         kx 
     5         kx   return $root;
     5         kx }
     5         kx 
     5         kx sub get_deps
     5         kx {
     5         kx   my $dir = shift;
     5         kx 
     5         kx   my $requires = $topdir . "/" . $dir . "/" . $target_build_dir . "/.requires";
     5         kx   my @deps = ();
     5         kx 
     5         kx   if( -f $requires )
     5         kx   {
     5         kx     open( FILE, '<', $requires ) or
     5         kx       _kxLab::error( "$0: Could not open $requires file: $!" );
     5         kx     while( <FILE> )
     5         kx     {
     5         kx       if( /all(: +)(.+)/ )
     5         kx       {
     5         kx         @deps = split( ' ', $2 );
     5         kx       }
     5         kx     }
     5         kx     close FILE;
     5         kx   }
     5         kx 
     5         kx   return @deps;
     5         kx }
     5         kx 
     5         kx sub get_tarball
     5         kx {
     5         kx   my $dir = shift;
     5         kx 
     5         kx   my $package = "";
     5         kx   my $proddir = $topdir . "/dist/products/" . $toolchain . "/" . $hardware;
     5         kx   my $dist    = $topdir . "/" . $dir . "/" . $target_build_dir . "/.dist";
     5         kx   my $patern;
     5         kx 
     5         kx   if( $flavour eq "" ) {
     5         kx     $patern = "^products/" . $toolchain . "/" . $hardware . "/(.+\.t?z)";
     5         kx   } else {
     5         kx     $patern = "^products/" . $toolchain . "/" . $hardware . "/" . $flavour . "/(.+\.t?z)";
     5         kx   }
     5         kx 
     5         kx   if( -f $dist )
     5         kx   {
     5         kx     open( FILE, '<', $dist ) or
     5         kx       _kxLab::error( "$0: Could not open $dist file: $!" );
     5         kx     foreach my $line ( <FILE> )
     5         kx     {
     5         kx       if( $line =~ /$patern/ )
     5         kx       {
     5         kx         # Existing packages only:
     5         kx         if( -f $proddir . "/" . $1 ) { $package = $1; }
     5         kx       }
     5         kx     }
     5         kx     close FILE;
     5         kx   }
     5         kx 
     5         kx   return $package;
     5         kx }
     5         kx 
     5         kx sub get_tarballs
     5         kx {
     5         kx   my $dir = shift;
     5         kx   my @deps = get_deps( $dir );
     5         kx 
     5         kx   foreach ( @deps )
     5         kx   {
     5         kx     my $tarball = get_tarball( $_ );
     5         kx     if( defined $tarball && $tarball ne "" )
     5         kx     {
     5         kx       push @tarballs, $tarball;
     5         kx     }
     5         kx 
     5         kx     get_tarballs( $_ );
     5         kx   }
     5         kx }
     5         kx 
     5         kx sub print_result
     5         kx {
     5         kx   my $format = shift;
     5         kx   my $out_string = "";
     5         kx 
     5         kx   if( $format eq "list" ) {
     5         kx     $out_string = sprintf( "####### Packages Install List: done\n" );
     5         kx   } else {
     5         kx     $out_string = sprintf( "####### Required Packages Tree: done\n" );
     5         kx   }
     5         kx 
     5         kx   print $out_string;
     5         kx }
     5         kx 
     5         kx 
     5         kx #
     5         kx # Parse the command line options
     5         kx #
     5         kx 
     5         kx # Get the rest arguments of the command line
     5         kx $format    = shift;
     5         kx $topdir    = shift;
     5         kx $toolchain = shift;
     5         kx $hardware  = shift;
     5         kx $flavour   = shift;
     5         kx 
     5         kx $format =~ tr/A-Z/a-z/;
     5         kx 
     5         kx my $cmd = "";
     5         kx my $srclist_suffix = "";
     5         kx 
     5         kx my $makefile = "Makefile";
     5         kx 
     5         kx if( ! defined $format    or $format eq "" )    { usage; }
     5         kx if( ! defined $topdir    or $topdir eq "" )    { usage; }
     5         kx if( ! defined $toolchain or $toolchain eq "" ) { usage; }
     5         kx if( ! defined $hardware  or $hardware eq "" )  { usage; }
     5         kx if( ! defined $flavour   or $flavour eq "" )   { $flavour = ""; }
     5         kx 
     5         kx _kxLab::error( "$0: $topdir is not a directory" ) if( ! -d $topdir );
     5         kx _kxLab::error( "$0: Makefile missing: $makefile" ) if ( ! -f $makefile );
     5         kx 
     5         kx $build_system = $topdir . "/build-system";
     5         kx 
     5         kx $system_version = system_version( $build_system );
     5         kx $distro_name    = distro_name( $build_system );
     5         kx $distro_version = distro_version( $build_system );
     5         kx $url            = bug_url( $build_system );
     5         kx 
     5         kx if( $flavour eq "" ) {
     5         kx   $target_build_dir  = "." . $toolchain . "/" . $hardware;
     5         kx } else {
     5         kx   $target_build_dir  = "." . $toolchain . "/" . $hardware . "/" . $flavour;
     5         kx }
     5         kx 
     5         kx if( $format eq "list" ) {
     5         kx   $srclist_suffix = ".srclist";
     5         kx } else {
     5         kx   $srclist_suffix = ".srctree";
     5         kx }
     5         kx 
     5         kx if( $flavour eq "" ) {
     5         kx   $srclist_file   = $target_build_dir . "/." . $hardware . $srclist_suffix;
     5         kx } else {
     5         kx   $srclist_file   = $target_build_dir . "/." . $hardware . "-" . $flavour . $srclist_suffix;
     5         kx }
     5         kx 
     5         kx 
     5         kx # open the output file:
     5         kx open( SRCLIST_FILE, '>', $srclist_file ) or
     5         kx   _kxLab::error( "$0: Could not open $srclist_file file: $!" );
     5         kx 
     5         kx 
     5         kx my $exclude = "";
     5         kx if( pkg_name( $makefile ) ne "init-devices" ) {
     5         kx   $exclude = " -e init-devices";
     5         kx   if( built_gcc_libs( $makefile ) eq "yes" && pkg_name( $makefile ) ne "gcc-runtime" ) {
     5         kx     $exclude .= ",gcc-runtime";
     5         kx   }
     5         kx }
     5         kx my $tree_format = " -t bin";
     5         kx 
     5         kx my $root = get_root();
     5         kx my $rpkg = get_tarball( $root );
     5         kx 
     5         kx get_tarballs( $root );
     5         kx @tarballs = uniq( @tarballs );
     5         kx 
     5         kx 
     5         kx my $tmpdir = $build_system . "/var/tmp";
     5         kx my $srcdir = $topdir . "/dist/products/" . $toolchain . "/" . $hardware;
     5         kx my $head   = $hardware;
     5         kx 
     5         kx 
     5         kx if( defined $rpkg && $rpkg ne "" ) {
     5         kx   $head = pkg_group( $makefile ) . "/" . pkg_name( $makefile )  . "-" . pkg_version( $makefile );
     5         kx   print SRCLIST_FILE $rpkg . "\n";
     5         kx }
     5         kx foreach ( @tarballs ) {
     5         kx   print SRCLIST_FILE $_ . "\n";
     5         kx }
     5         kx 
     5         kx if( $format eq "list" ) {
     5         kx   $cmd = "TMP=" . $tmpdir . " " . $build_system . "/sbin/make-pkglist" .
     5         kx          " -w " . $hardware . " -H " . $head . $exclude .
     5         kx          " -i pkg -o list -s " . $srcdir .
     5         kx          " -F " . $srclist_file . " " . $target_build_dir . "/";
     5         kx } else {
     5         kx   $cmd = "TMP=" . $tmpdir . " " . $build_system . "/sbin/make-pkglist" .
     5         kx          " -w " . $hardware . " -H " . $head . $exclude .
     5         kx          " -i pkg" . $tree_format . " -o json -m -s " . $srcdir .
     5         kx          " -F " . $srclist_file . " " . $target_build_dir . "/";
     5         kx }
     5         kx 
     5         kx # close output file:
     5         kx close SRCLIST_FILE;
     5         kx 
     5         kx _kxLab::system( "$cmd" );
     5         kx 
     5         kx #
     5         kx # Copy Packages List to the TARGET_BUILD_DIR (for release compatibility):
     5         kx #
     5         kx if( $format eq "list" && $head ne $hardware ) {
     5         kx   $cmd = "cp -a " . $target_build_dir . "/" . $head . ".pkglist " . $target_build_dir . "/" . $hardware . ".pkglist";
     5         kx   _kxLab::system( "$cmd" );
     5         kx }
     5         kx 
     5         kx print "#######\n";
     5         kx print_result( $format );
     5         kx print "#######\n";