Rev 6887 | Blame | Compare with Previous | Last modification | View Log | RSS feed
#! perl######################################################################### COPYRIGHT - VIX IP PTY LTD ("VIX"). ALL RIGHTS RESERVED.## Module name : jats.sh# Module type : Makefile system# Compiler(s) : n/a# Environment(s): jats## Description : Package Entry## New Create a new package entry instance.## RuleInc Check whether the specific 'include' path should# be included within the PINCDIRS list.## RuleLib Check whether the specific 'lib' path should# be included within the PLIBDIRS list.## Cleanup Performs any record cleanup required prior to the# entry being published.## Usage:## Version Who Date Description##......................................................................#require 5.006_001;use strict;use warnings;use DescPkg;use JatsError;our $BUILDNAME_PACKAGE;our $BUILDNAME_VERSION;our $BUILDNAME_PROJECT;our $BUILDINTERFACE;our @BUILDTOOLS;package PackageEntry;our %DescPkgCache = (); # Hash of known packagesour %PackageDefined = (); # Quick defined package testour @PackageList = (); # Ordered array of packages#-------------------------------------------------------------------------------# Function : EmptyEntry## Description : Create an empty class element# Populated with the basic items## Inputs : None## Returns : New, empty entry#sub EmptyEntry{my ($self) = {PINCDIRS => [],PLIBDIRS => [],LIBEXAMINED => {},INCEXAMINED => {},TOOLDIRS => [],THXDIRS => [],};return bless $self, __PACKAGE__;}#-------------------------------------------------------------------------------# Function : New## Description : Create a new instance of the PackageEntry class## Inputs : $base - Path to the package# $name - Package Name# $version - Version# $type - 'link' or 'build'# $local - Is from a local archive# No version check.# Display path to package# $pkgSig - Package Signature## Returns :#sub New{my ($base, $name, $version, $type, $local, $pkgSig) = @_;my $self = EmptyEntry();# Load package description ...# Note: The results are cached within DescPkgCache#..if ( ! exists( $DescPkgCache{$base} ) ){my ($rec);my ($desc) = "";if ( -f "$base/descpkg" ){$rec = ::ReadDescpkg( "$base/descpkg", 1 );}else{ # doesn't exist::Error( "Package description does not exist","Package Location: $base" )}::Error("Cannot determine package description","Package Location: $base" )unless ( $rec );::Warning( "Package names do not match: $rec->{NAME}, $name" )if ( $rec->{NAME} ne $name );if ( $local ){ # display resultsmy $logPrefix = " ->";::Log( "$logPrefix $base" );}elsif ( $rec->{VERSION_FULL} ne $version ){::Warning( "Package versions do not match: $name : $rec->{VERSION_FULL}, $version" );}## Extend the package information to contain sufficient data# for general use. Information will be retained to allow the# user to extact specific package information#$version =~ m~(\d+\.\d+\.\d+)\.(\w+)~ ;my $vnum = $1 || $version;my $proj = $2 || '';$rec->{UNAME} = $name;$rec->{UVERSION} = $version;$rec->{UVNUM} = $vnum;$rec->{UPROJ} = $proj;$rec->{type} = $type;$rec->{PKGSIG} = $pkgSig;$PackageDefined{$name}{$proj}{$vnum} = $base;push @PackageList, $base;$DescPkgCache{$base} = $rec; # cache result}# Build the package entry record#..my ($descpkg) = $DescPkgCache{$base}; # descpkg details$self->{'base'} = $base;$self->{'name'} = $name;$self->{'version'} = $version;$self->{'dname'} = $descpkg->{NAME};$self->{'dversion'} = $descpkg->{VERSION};$self->{'dproj'} = $descpkg->{PROJ} || $descpkg->{UPROJ} || '';$self->{'packages'} = $descpkg->{PACKAGES};$self->{'type'} = $type;$self->{'sandbox'} = $local;$self->{'cfgdir'} = "/gbe" if ( -d $base."/gbe" );# $self->{pkgsig} = $descpkg->{PKGSIG};return $self;}#-------------------------------------------------------------------------------# Function : Interface## Description : Create a specialised 'interface' entry## Inputs : $base - Path to the Interface directory## Returns : Ref to this class#sub Interface{my ($base) = @_;my $self = EmptyEntry();$self->{'base'} = $base;$self->{'name'} = 'INTERFACE';$self->{'version'} = '0.0.0';$self->{'dname'} = $self->{'name'};$self->{'dversion'} = $self->{'version'};$self->{'dproj'} = '';$self->{'packages'} = '';$self->{'type'} = 'interface';$self->{'cfgdir'} = '/gbe';return $self;}sub RuleInc{my( $self ) = shift;my( $path ) = @_;my( $examined ) = $self->{INCEXAMINED};my( $list ) = $self->{PINCDIRS};return if ( $$examined{$path} );$$examined{$path} = 1;push @$list, $path if ( -d $self->{'base'}.$path );}## Examine Path to ensure that it is a directory and that it contains files# Simplify Lib Path searching by removing useless paths.## If there are ANY files then the directory is useful# If there are no files ( only subdirectories ) then the directory is not useful#sub isUsefulDir{my ($path) = @_;if ( -d $path ){opendir (USEFUL, $path) or ::Error ("Cannot open $path");my @dirlist = readdir USEFUL;closedir USEFUL;foreach ( @dirlist ){return 1 if ( -f "$path/$_" );}}return 0;}sub RuleLib{my( $self ) = shift;my( $path ) = @_;my( $examined ) = $self->{LIBEXAMINED};my( $list ) = $self->{PLIBDIRS};return if ( $$examined{$path} );$$examined{$path} = 1;push @$list, $path."D" if ( isUsefulDir($self->{'base'}.$path."D") );push @$list, $path."P" if ( isUsefulDir($self->{'base'}.$path."P") );push @$list, $path if ( isUsefulDir($self->{'base'}.$path) );}#-------------------------------------------------------------------------------# Function : ExamineToolPath## Description : Given the root of a package, locate any# toolset extension paths within the tree. These will be# saved and later used when user tools and scripts are# invoked.## Examine:# - tools/bin/GBE_MACHTYPE/bin - Hardware specfic tools# - tools/bin/GBE_MACHTYPE - Hardware specfic tools# - tools/bin - Hardware independent tools - scripts# - tools/scripts/GBE_MACHINE - Hardware specific scripts# - tools/scripts - Hardware independent scripts (too)## Inputs : self## Returns : Nothing#sub ExamineToolPath{my( $self ) = shift;## Determine base dir# LinkPkgArchive : From the package# BuildPkgArchive : From the interface directory#my $pbase_dir = $self->{'base'}; # Package relative base directorymy $base_dir = $self->{'base'}; # Base directory to use$base_dir = "$::CwdFull/$BUILDINTERFACE"if ( $self->{'type'} eq 'build' );my @searchList;my $path = "/tools/bin";foreach my $suffix ( "/$::GBE_MACHTYPE", "/$::GBE_MACHTYPE/bin", "" ) {push @searchList, $path . $suffix;}$path = "/tools/scripts";foreach my $suffix ( "/$::GBE_MACHTYPE", "" ) {push @searchList, $path . $suffix;}for my $path (@searchList ){# Test against the Package Directory# So that we correctly identify packages witg tools# Store the Use base directory# So that BuildPkgArchive will be in the interfacemy $dir = $base_dir . $path;if ( isUsefulDir( $pbase_dir . $path ) ){::UniquePush( \@{$self->{'TOOLDIRS'}}, $dir );::UniquePush( \@BUILDTOOLS, $dir );}}}#-------------------------------------------------------------------------------# Function : ExamineThxPath## Description : Given the root of a package, locate some well known# packaging directories for later use.## Examine:# /thx/$platform# /thx## Inputs : self# platform - Current build platform## Returns : nothing#sub ExamineThxPath{my( $self, $platform ) = @_;my $dir = $self->{'base'} . '/thx';if ( -d $dir ){push @{$self->{'THXDIRS'}}, "/thx/$platform" if isUsefulDir( "$dir/$platform" );push @{$self->{'THXDIRS'}}, "/thx" if isUsefulDir( $dir );}}sub Cleanup{my ($self) = shift;delete $self->{LIBEXAMINED};delete $self->{INCEXAMINED};}#-------------------------------------------------------------------------------# Function : GetBaseDir## Description : Return the base directory of a given package# Simple getter function## Inputs : self# path - Optional path within package## Returns : The base directory of the package#sub GetBaseDir{my ($self, $path) = @_;my $dir = $self->{'base'};$dir .= '/' . $path if ( $path );return $dir;}#-------------------------------------------------------------------------------# Function : SanityTest## Description : Examine all the packages used in the current build.pl# and all the packages used to build them. Then generate# warning if there are mismatches.## All the data has been collected and stored within# $DescPkgCache. This routine processes the data and# constructs a data structure to locate packages with# multiple versions.## The project name is considered to be a part of the package# name. Thus aaaa_11.22.33.mass is different to aaaa_11.22.33.syd## Inputs :## Returns :#my %package_list;sub AddEntry{my( $root, $rver, $rproj, $name, $version ) = @_;my $ver;my $proj;if ($version eq "!current") {$ver = "current";$proj = "";} else {$version =~ m~(.*)\.(.*?)$~;$ver = $1 || 'BadVer';$proj = $2 || 'BadProj';}::UniquePush( \@{$package_list{"$name$;$proj"}{$ver}}, "${root}_${rver}.${rproj}");}sub SanityTest{foreach my $package ( keys %DescPkgCache ){my $pptr = $DescPkgCache{$package};my $lver = $pptr->{'VERSION'};$lver .= '.' . $pptr->{'PROJ'} if ( $pptr->{'PROJ'} );AddEntry( $BUILDNAME_PACKAGE, $BUILDNAME_VERSION, $BUILDNAME_PROJECT, $pptr->{'NAME'}, $lver );foreach my $subpkg ( @{$pptr->{'PACKAGES'}} ){my $name = $subpkg->{name};my $ver = $subpkg->{version};AddEntry( $pptr->{'NAME'}, $pptr->{'VERSION'}, $pptr->{'PROJ'}, $name, $ver );}}#::DebugDumpData("XXX", \%package_list );## Detect and print warnings about multiple entries#my $first_found = 0;foreach my $pentry ( sort keys %package_list){my @versions = keys %{$package_list{$pentry}};if ( $#versions > 0 ){::Warning("Package mismatchs detected.") unless ( $first_found++ );my ($pname, $pproj) = split $;, $pentry ;foreach my $version ( @versions ){::Warning("Package ${pname}_${version}.${pproj} used by:", @{$package_list{$pentry}{$version}});}}}}#-------------------------------------------------------------------------------# Function : Exists## Description : A class function to determine if a given package is known# to the PackageEntry manager. Used to detect multiple package# definitions.## The test ignores package versions# It is not possible to include different versions of the# same package. The test ignores the project part of the# version. This allows for# sysbasetypes aa.bb.cc.mas and# sysbasetypes xx.yy.zz.syd## Inputs : $name - User package name# $version - User version ( with project )## Returns : True: Package exists#sub Exists{my ($name, $version) = @_;$version =~ m~(\d+\.\d+\.\d+)\.(\w+)~ ;my $vnum = $1 || $version;my $proj = $2 || '';return exists( $PackageDefined{$name}{$proj} );}#-------------------------------------------------------------------------------# Function : GetPackageList## Description : A class function to return a list of packages# The list cannot be used directly. It is really a set of# keys to an internal data structure.## The result can be used to iterate over the list of packages# using other functions.## Inputs : None## Returns : An array of package tags# The array is ordered by package definition order#sub GetPackageList{return @PackageList;}#-------------------------------------------------------------------------------# Function : GetPackageData## Description : A class function to return specific data for a given package## Inputs : $tag - An iteration tag provided by GetPackageList()## Returns : A list of# Package name# Package version# Package type : build or link#sub GetPackageData{my ($tag) = @_;my $rec = $DescPkgCache{$tag};return $rec->{UNAME}, $rec->{UVERSION}, $rec->{type};}#-------------------------------------------------------------------------------# Function : GetNameVersion## Description : Return a package name and version for display purposes## Inputs : $tag - An iteration tag provided by GetPackageList()## Returns : A list of# Package name# Package version# Package type : build or link#sub GetNameVersion{my ($tag) = @_;my $rec = $DescPkgCache{$tag};return join( ' ', $rec->{NAME}, $rec->{VERSION_FULL} );}#-------------------------------------------------------------------------------# Function : GetPackageVersionList## Description : A class function to return a list of package names as used# to generate version strings### Inputs : None## Returns : An array of version list entries# Each element of the form: "name (version)"#sub GetPackageVersionList{my @list;foreach my $tag ( @PackageList ){my $rec = $DescPkgCache{$tag};push @list, "$rec->{UNAME} ($rec->{UVERSION})";}return @list;}#-------------------------------------------------------------------------------# Function : GetPackageSignature## Description : A class function to return a packages signature### Inputs : None## Returns : An array of version list entries# Each element of the form: "name (version)"#sub GetPackageSignature{my ($tag) = @_;my $rec = $DescPkgCache{$tag};return $rec->{PKGSIG};}#-------------------------------------------------------------------------------# Function : Dump## Description : Internal diagnostic tool# Dumps internal data structures## Inputs : None## Returns : Nothing#sub Dump{::DebugDumpData("PackageEntry",\%DescPkgCache);}### End of package: PackageEntry1;