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 use Getopt::Long;
     5         kx 
     5         kx use _kxLab;
     5         kx 
     5         kx #
     5         kx # Generate .src_requires file for current directory
     5         kx #
     5         kx # usage:
     5         kx #   $0 [options] topdir
     5         kx #
     5         kx # where:
     5         kx #   'topdir' - is a absolute path to the top directory of checked out branch
     5         kx #
     5         kx 
     5         kx 
     5         kx # global variables
     5         kx my (%all_requires, $top_dir, $opt_max_depth, %requires_depend, $requires_file, %skip_dirs);
     5         kx 
     5         kx my %all_src_requires;
     5         kx 
     5         kx 
     5         kx sub usage
     5         kx {
     5         kx   print <<EOF;
     5         kx 
     5         kx Usage: build_requires [options] topdir
     5         kx Options:
     5         kx    --max-depth=i - where 'i' is a maximal directory depth for finding requires;
     5         kx       --skip-dir - directory to be skipped (such as dist or TARGET_BUILD_DIR);
     5         kx           topdir - is a absolute path to the top of checked out branch.
     5         kx 
     5         kx EOF
     5         kx   exit;
     5         kx }
     5         kx 
     5         kx 
     5         kx sub requires_depend
     5         kx {
     5         kx   my $makefile = shift;
     5         kx 
     5         kx   if( ! exists $requires_depend{$makefile} )
     5         kx   {
     5         kx     print REQUIRES_DEPEND_FILE "$requires_file: $makefile\n\n";
     5         kx     print REQUIRES_DEPEND_FILE "$makefile:\n\n";
     5         kx     $requires_depend{$makefile} = "";
     5         kx   }
     5         kx }
     5         kx 
     5         kx sub read_src_requires
     5         kx {
     5         kx   my $makefile  = shift;
     5         kx 
     5         kx   # add a dependency to the Makefile
     5         kx   requires_depend($makefile);
     5         kx 
     5         kx   my %requires;
     5         kx 
     5         kx   my $shell_output = `cat $makefile`;
     5         kx 
     5         kx   while( $shell_output =~ m/^SOURCE_REQUIRES(.+= +)(.+)/gm )
     5         kx   {
     5         kx     my @n = split( " ", $2 );
     5         kx     foreach my $d ( @n )
     5         kx     {
     5         kx       if( $d eq "ALL_DIRS" )
     5         kx       {
     5         kx         my $dirname = dirname($makefile);
     5         kx 
     5         kx         opendir( DIR, "$dirname" ) or
     5         kx           _kxLab::error( "build_src_requires: Could not open directory: $dirname: $!" );
     5         kx         my @dirs = grep { ! /^\./ && -d "$_" && -f "$_/Makefile" } readdir( DIR );
     5         kx         closedir DIR;
     5         kx 
     5         kx         foreach my $dir (@dirs)
     5         kx         {
     5         kx           requires_depend("$dirname/$dir/Makefile");
     5         kx           "$dirname/$dir" =~ m!$top_dir/(.+)!;
     5         kx           $requires{$1} = "";
     5         kx         }
     5         kx       }
     5         kx       else
     5         kx       {
     5         kx         # Print a nice error message if the SOURCE_REQUIRES statement points to a missing directory
     5         kx         _kxLab::error( "build_src_requires: SOURCE_REQUIRES '$d' in $makefile not found. Exit" ) if( ! -d "$top_dir/$d" );
     5         kx 
     5         kx         if( -f "$top_dir/$d/Makefile" )
     5         kx         {
     5         kx           $requires{$d} = "";
     5         kx           requires_depend("$top_dir/$d/Makefile");
     5         kx         }
     5         kx       }
     5         kx     }
     5         kx   }
     5         kx   return %requires;
     5         kx }
     5         kx 
     5         kx sub read_requires
     5         kx {
     5         kx   my $makefile  = shift;
     5         kx 
     5         kx   # add a dependency to the Makefile
     5         kx   requires_depend($makefile);
     5         kx 
     5         kx   my %requires;
     5         kx 
     5         kx   my $shell_output = `cat $makefile`;
     5         kx 
     5         kx   while( $shell_output =~ m/^REQUIRES(.+= +)(.+)/gm )
     5         kx   {
     5         kx     my @n = split( " ", $2 );
     5         kx     foreach my $req ( @n )
     5         kx     {
     5         kx       my $d = `echo $req | cut -f 1 -d '^'`;
     5         kx       $d =~ s/^\s+|\s+$//;
     5         kx 
     5         kx       if( $d eq "ALL_DIRS" )
     5         kx       {
     5         kx         my $dirname = dirname($makefile);
     5         kx 
     5         kx         opendir( DIR, "$dirname" ) or
     5         kx           _kxLab::error( "build_src_requires: Could not open directory: $dirname: $!" );
     5         kx         my @dirs = grep { ! /^\./ && -d "$_" && -f "$_/Makefile" } readdir( DIR );
     5         kx         closedir DIR;
     5         kx 
     5         kx         foreach my $dir (@dirs)
     5         kx         {
     5         kx           requires_depend( "$dirname/$dir/Makefile" );
     5         kx           "$dirname/$dir" =~ m!$top_dir/(.+)!;
     5         kx           $requires{$1} = "";
     5         kx 
     5         kx           my %src_requires = read_src_requires( "$dirname/$dir/Makefile" );
     5         kx           my @sort_src_requires = sort(keys %src_requires);
     5         kx           foreach my $req ( @sort_src_requires )
     5         kx           {
     5         kx             $all_src_requires{$req} = "";
     5         kx           }
     5         kx         }
     5         kx       }
     5         kx       else
     5         kx       {
     5         kx         # Print a nice error message if the REQUIRES statement points to a missing directory
     5         kx         _kxLab::error( "build_src_requires: REQUIRES '$d' in $makefile not found. Exit" ) if( ! -d "$top_dir/$d" );
     5         kx 
     5         kx         if( -f "$top_dir/$d/Makefile" )
     5         kx         {
     5         kx           $requires{$d} = "";
     5         kx 
     5         kx           my %src_requires = read_src_requires( "$top_dir/$d/Makefile" );
     5         kx           my @sort_src_requires = sort(keys %src_requires);
     5         kx           foreach my $req ( @sort_src_requires )
     5         kx           {
     5         kx             $all_src_requires{$req} = "";
     5         kx           }
     5         kx         }
     5         kx       }
     5         kx     }
     5         kx   }
     5         kx   return %requires;
     5         kx }
     5         kx 
     5         kx sub start_depend
     5         kx {
     5         kx   my $req = shift;
     5         kx 
     5         kx   print REQUIRES_FILE "$req:";
     5         kx }
     5         kx 
     5         kx sub depend
     5         kx {
     5         kx   my $req = shift;
     5         kx 
     5         kx   print REQUIRES_FILE " $req";
     5         kx }
     5         kx 
     5         kx sub end_depend
     5         kx {
     5         kx   print REQUIRES_FILE "\n\n";
     5         kx }
     5         kx 
     5         kx sub make_sub_requires
     5         kx {
     5         kx   my $req = shift;
     5         kx 
     5         kx   if( ! exists $all_requires{$req} )
     5         kx   {
     5         kx     $all_requires{$req} = "";
     5         kx 
     5         kx     my $d = `echo $req | cut -f 1 -d '^'`;
     5         kx     $d =~ s/^\s+|\s+$//;
     5         kx 
     5         kx     # Read sub requires
     5         kx     my $makefile = "$top_dir/$d/Makefile";
     5         kx     my %sub_requires = read_requires( $makefile );
     5         kx     if( scalar(%sub_requires) )
     5         kx     {
     5         kx       # Make sub sub requires
     5         kx       my @sorted_sub_requires = sort(keys %sub_requires);
     5         kx       foreach my $sub_req ( @sorted_sub_requires )
     5         kx       {
     5         kx         make_sub_requires( $sub_req );
     5         kx       }
     5         kx     }
     5         kx   }
     5         kx }
     5         kx 
     5         kx 
     5         kx #
     5         kx # Parse the command line options
     5         kx #
     5         kx $opt_max_depth = 10;
     5         kx my @opt_skip_dirs;
     5         kx GetOptions( "max-depth=i" => \$opt_max_depth, "skip-dir=s" => \@opt_skip_dirs );
     5         kx %skip_dirs = map { $_ => "" } @opt_skip_dirs;
     5         kx 
     5         kx # get the rest of the command line
     5         kx my $topdir   = shift;
     5         kx my $makefile = "Makefile";
     5         kx 
     5         kx if( ! defined $topdir or $topdir eq "" ) { usage; }
     5         kx 
     5         kx _kxLab::error( "build_requires: $topdir is not a directory" ) if( ! -d $topdir );
     5         kx _kxLab::error( "build_requires: Makefile missing: $makefile" ) if ( ! -f $makefile );
     5         kx 
     5         kx # setup $top_build_dir
     5         kx $top_dir = $topdir;
     5         kx 
     5         kx $requires_file = ".src_requires";
     5         kx my $requires_depend_file = $requires_file . "_depend";
     5         kx 
     5         kx 
     5         kx # open the output files
     5         kx open(REQUIRES_FILE, "> $requires_file") or
     5         kx   _kxLab::error( "build_requires: Could not open $requires_file file: $!" );
     5         kx open(REQUIRES_DEPEND_FILE, "> $requires_depend_file") or
     5         kx   _kxLab::error( "build_requires: Could not open $requires_depend_file file: $!" );
     5         kx 
     5         kx 
     5         kx # root component
     5         kx my $pwd = `pwd`;
     5         kx chomp $pwd;
     5         kx $pwd =~ m!$top_dir(.*)!;
     5         kx my $root;
     5         kx if( $1 eq "" )
     5         kx {
     5         kx   $root = "all";
     5         kx }
     5         kx else
     5         kx {
     5         kx   $1 =~ m!/(.+)!;
     5         kx   $root = $1;
     5         kx }
     5         kx 
     5         kx print REQUIRES_FILE "# ROOT=$root\n\n";
     5         kx print REQUIRES_DEPEND_FILE "\n";
     5         kx 
     5         kx # read the makefile
     5         kx %all_src_requires = read_src_requires( "$pwd/$makefile" );
     5         kx my %requires = read_requires( "$pwd/$makefile" );
     5         kx 
     5         kx 
     5         kx # check the "build-system" sub dependencies implicitly (excluding sources directories)
     5         kx #$requires{"build-system"} = "";
     5         kx 
     5         kx 
     5         kx # build sub dependencies
     5         kx my @sorted_requires = sort(keys %requires);
     5         kx foreach my $req ( @sorted_requires )
     5         kx {
     5         kx   make_sub_requires( $req );
     5         kx }
     5         kx 
     5         kx # build the all: rule
     5         kx start_depend( "all" );
     5         kx my @sorted_src_requires = sort(keys %all_src_requires);
     5         kx foreach my $req ( @sorted_src_requires )
     5         kx {
     5         kx   depend( $req );
     5         kx }
     5         kx end_depend();
     5         kx 
     5         kx 
     5         kx # Finish by including tree.mk
     5         kx print REQUIRES_FILE "TREEDIRS = ", join(" ", sort(keys %all_src_requires)), "\n\n";
     5         kx print REQUIRES_FILE "include \$(BUILDSYSTEM)/tree-src.mk\n";
     5         kx 
     5         kx 
     5         kx # close output files
     5         kx close REQUIRES_FILE;
     5         kx close REQUIRES_DEPEND_FILE;