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";