Subversion Repositories DevTools

Rev

Rev 6887 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
227 dpurdie 1
#! perl
2
########################################################################
6177 dpurdie 3
# COPYRIGHT - VIX IP PTY LTD ("VIX"). ALL RIGHTS RESERVED.
227 dpurdie 4
#
5
# Module name   : jats.sh
6
# Module type   : Makefile system
7
# Compiler(s)   : n/a
8
# Environment(s): jats
9
#
10
# Description   : Package Entry
11
#
12
#       New         Create a new package entry instance.
13
#
14
#       RuleInc     Check whether the specific 'include' path should
15
#                   be included within the PINCDIRS list.
16
#
17
#       RuleLib     Check whether the specific 'lib' path should
18
#                   be included within the PLIBDIRS list.
19
#
20
#       Cleanup     Performs any record cleanup required prior to the
21
#                   entry being published.
22
#
23
# Usage:
24
#
25
# Version   Who      Date        Description
26
#
27
#......................................................................#
28
 
255 dpurdie 29
require 5.006_001;
227 dpurdie 30
use strict;
31
use warnings;
32
 
33
use DescPkg;
34
use JatsError;
35
 
36
 
37
our $BUILDNAME_PACKAGE;
38
our $BUILDNAME_VERSION;
39
our $BUILDNAME_PROJECT;
40
our $BUILDINTERFACE;
41
our @BUILDTOOLS;
42
 
43
 
44
package PackageEntry;
45
 
46
our %DescPkgCache           = ();           # Hash of known packages
47
our %PackageDefined         = ();           # Quick defined package test
48
our @PackageList            = ();           # Ordered array of packages
49
 
311 dpurdie 50
 
51
#-------------------------------------------------------------------------------
52
# Function        : EmptyEntry
53
#
54
# Description     : Create an empty class element
55
#                   Populated with the basic items
56
#
57
# Inputs          : None
58
#
59
# Returns         : New, empty entry
60
#
61
sub EmptyEntry
227 dpurdie 62
{
63
    my ($self) = {
64
            PINCDIRS        => [],
65
            PLIBDIRS        => [],
66
            LIBEXAMINED     => {},
67
            INCEXAMINED     => {},
68
            TOOLDIRS        => [],
69
            THXDIRS         => [],
70
        };
311 dpurdie 71
    return bless $self, __PACKAGE__;
72
}
6276 dpurdie 73
#-------------------------------------------------------------------------------
74
# Function        : New 
75
#
76
# Description     : Create a new instance of the PackageEntry class
77
#
78
# Inputs          : $base           - Path to the package
79
#                   $name           - Package Name
80
#                   $version        - Version
81
#                   $type           - 'link' or 'build'
82
#                   $local          - Is from a local archive
83
#                                     No version check.
84
#                                     Display path to package
85
#                   $pkgSig         - Package Signature
86
#
87
# Returns         : 
88
#
227 dpurdie 89
 
311 dpurdie 90
sub New
91
{
6276 dpurdie 92
    my ($base, $name, $version, $type, $local, $pkgSig) = @_;
311 dpurdie 93
    my $self = EmptyEntry();
94
 
95
    #   Load package description ...
96
    #   Note:   The results are cached within DescPkgCache
97
    #..
227 dpurdie 98
    if ( ! exists( $DescPkgCache{$base} ) )
99
    {
100
        my ($rec);
101
        my ($desc) = "";
102
 
6276 dpurdie 103
        if ( -f "$base/descpkg" )
227 dpurdie 104
        {
105
            $rec = ::ReadDescpkg( "$base/descpkg", 1 );
106
        }
107
        else
108
        {                                       # doesn't exist
109
            ::Error( "Package description does not exist",
110
                     "Package Location: $base" )
111
        }
112
 
113
        ::Error("Cannot determine package description",
114
                "Package Location: $base" )
115
            unless ( $rec );
116
 
117
        ::Warning( "Package names do not match: $rec->{NAME}, $name" )
118
            if ( $rec->{NAME} ne $name );
119
 
6276 dpurdie 120
        if ( $local )
227 dpurdie 121
        {                                       # display results
331 dpurdie 122
            my $logPrefix = "               ->";
6276 dpurdie 123
            ::Log( "$logPrefix $base" );
227 dpurdie 124
        }
125
        elsif ( $rec->{VERSION_FULL} ne $version )
126
        {
127
            ::Warning( "Package versions do not match: $name : $rec->{VERSION_FULL}, $version" );
128
        }
129
 
130
        #
6177 dpurdie 131
        #   Extend the package information to contain sufficient data
227 dpurdie 132
        #   for general use. Information will be retained to allow the
133
        #   user to extact specific package information
134
        #
135
        $version =~ m~(\d+\.\d+\.\d+)\.(\w+)~ ;
136
        my $vnum = $1 || $version;
137
        my $proj = $2 || '';
138
 
139
        $rec->{UNAME}    = $name;
140
        $rec->{UVERSION} = $version;
141
        $rec->{UVNUM}    = $vnum;
142
        $rec->{UPROJ}    = $proj;
143
        $rec->{type}     = $type;
6276 dpurdie 144
        $rec->{PKGSIG}   = $pkgSig;
227 dpurdie 145
 
146
        $PackageDefined{$name}{$proj}{$vnum} = $base;
147
        push @PackageList, $base;
148
 
149
        $DescPkgCache{$base} = $rec;                  # cache result
150
    }
151
 
152
#   Build the package entry record
153
#..
154
    my ($descpkg) = $DescPkgCache{$base};       # descpkg details
155
 
156
    $self->{'base'}         = $base;
157
 
158
    $self->{'name'}         = $name;
159
    $self->{'version'}      = $version;
160
    $self->{'dname'}        = $descpkg->{NAME};
161
    $self->{'dversion'}     = $descpkg->{VERSION};
162
    $self->{'dproj'}        = $descpkg->{PROJ} || $descpkg->{UPROJ} || '';
163
    $self->{'packages'}     = $descpkg->{PACKAGES};
164
    $self->{'type'}         = $type;
6887 dpurdie 165
    $self->{'sandbox'}      = $local;
6276 dpurdie 166
    $self->{'cfgdir'}       = "/gbe" if ( -d $base."/gbe" );
167
#    $self->{pkgsig}         = $descpkg->{PKGSIG};
227 dpurdie 168
 
311 dpurdie 169
    return $self;
227 dpurdie 170
}
171
 
311 dpurdie 172
#-------------------------------------------------------------------------------
173
# Function        : Interface
174
#
175
# Description     : Create a specialised 'interface' entry
176
#
177
# Inputs          : $base           - Path to the Interface directory
178
#
179
# Returns         : Ref to this class
180
#
181
sub Interface
182
{
183
    my ($base) = @_;
184
    my $self = EmptyEntry();
185
 
186
    $self->{'base'}         = $base;
187
    $self->{'name'}         = 'INTERFACE';
188
    $self->{'version'}      = '0.0.0';
189
    $self->{'dname'}        = $self->{'name'};
190
    $self->{'dversion'}     = $self->{'version'};
191
    $self->{'dproj'}        = '';
192
    $self->{'packages'}     = '';
193
    $self->{'type'}         = 'interface';
194
    $self->{'cfgdir'}       = '/gbe';
195
 
196
    return $self;
197
 
198
}
199
 
227 dpurdie 200
sub RuleInc
201
{
202
    my( $self ) = shift;
203
    my( $path ) = @_;
204
    my( $examined ) = $self->{INCEXAMINED};
205
    my( $list ) = $self->{PINCDIRS};
206
 
207
    return if ( $$examined{$path} );
208
    $$examined{$path} = 1;
209
 
6276 dpurdie 210
    push @$list, $path      if ( -d $self->{'base'}.$path );
227 dpurdie 211
}
212
 
213
#
214
#   Examine Path to ensure that it is a directory and that it contains files
215
#   Simplify Lib Path searching by removing useless paths.
216
#
217
#   If there are ANY files then the directory is useful
218
#   If there are no files ( only subdirectories ) then the directory is not useful
219
#
220
sub isUsefulDir
221
{
222
    my ($path) = @_;
223
 
224
    if ( -d $path )
225
    {
226
        opendir (USEFUL, $path) or ::Error ("Cannot open $path");
227
        my @dirlist = readdir USEFUL;
285 dpurdie 228
        closedir USEFUL;
227 dpurdie 229
 
230
        foreach ( @dirlist )
231
        {
232
            return 1 if ( -f "$path/$_" );
233
        }
234
    }
235
    return 0;
236
}
237
 
238
sub RuleLib
239
{
240
    my( $self ) = shift;
241
    my( $path ) = @_;
242
    my( $examined ) = $self->{LIBEXAMINED};
243
    my( $list ) = $self->{PLIBDIRS};
244
 
245
    return if ( $$examined{$path} );
246
    $$examined{$path} = 1;
247
 
6276 dpurdie 248
    push @$list, $path."D"  if ( isUsefulDir($self->{'base'}.$path."D") );
249
    push @$list, $path."P"  if ( isUsefulDir($self->{'base'}.$path."P") );
250
    push @$list, $path      if ( isUsefulDir($self->{'base'}.$path) );
227 dpurdie 251
}
252
 
253
#-------------------------------------------------------------------------------
254
# Function        : ExamineToolPath
255
#
256
# Description     : Given the root of a package, locate any
257
#                   toolset extension paths within the tree. These will be
258
#                   saved and later used when user tools and scripts are
259
#                   invoked.
260
#
261
#   Examine:
6511 dpurdie 262
#       - tools/bin/GBE_MACHTYPE/bin    - Hardware specfic tools
263
#       - tools/bin/GBE_MACHTYPE        - Hardware specfic tools
264
#       - tools/bin                     - Hardware independent tools - scripts
265
#       - tools/scripts/GBE_MACHINE     - Hardware specific scripts
266
#       - tools/scripts                 - Hardware independent scripts (too)
227 dpurdie 267
#
268
# Inputs          : self
269
#
270
# Returns         : Nothing
271
#
272
sub ExamineToolPath
273
{
274
    my( $self ) = shift;
275
 
276
    #
277
    #   Determine base dir
278
    #       LinkPkgArchive  : From the package
279
    #       BuildPkgArchive : From the interface directory
280
    #
7433 dpurdie 281
    my $pbase_dir = $self->{'base'};                        # Package relative base directory
282
    my $base_dir = $self->{'base'};                         # Base directory to use
283
    $base_dir = "$::CwdFull/$BUILDINTERFACE"
227 dpurdie 284
        if ( $self->{'type'} eq 'build' );
285
 
6504 dpurdie 286
    my @searchList;
287
    my $path = "/tools/bin";
6511 dpurdie 288
    foreach my $suffix ( "/$::GBE_MACHTYPE", "/$::GBE_MACHTYPE/bin", "" ) {
6504 dpurdie 289
        push @searchList, $path . $suffix;
290
    }
291
 
292
    $path = "/tools/scripts";
293
    foreach my $suffix ( "/$::GBE_MACHTYPE", "" ) {
294
        push @searchList, $path . $suffix;
295
    }
296
 
297
    for my $path (@searchList )
227 dpurdie 298
    {
7433 dpurdie 299
        #   Test against the Package Directory
300
        #       So that we correctly identify packages witg tools
301
        #   Store the Use base directory
302
        #       So that BuildPkgArchive will be in the interface    
303
 
6504 dpurdie 304
        my $dir = $base_dir . $path;
7433 dpurdie 305
        if ( isUsefulDir( $pbase_dir . $path ) )
227 dpurdie 306
        {
6504 dpurdie 307
            ::UniquePush( \@{$self->{'TOOLDIRS'}}, $dir );
308
            ::UniquePush( \@BUILDTOOLS, $dir );
227 dpurdie 309
        }
310
    }
311
}
312
 
313
#-------------------------------------------------------------------------------
314
# Function        : ExamineThxPath
315
#
316
# Description     : Given the root of a package, locate some well known
317
#                   packaging directories for later use.
318
#
319
#                   Examine:
320
#                       /thx/$platform
321
#                       /thx
322
#
323
# Inputs          : self
324
#                   platform        - Current build platform
325
#
326
# Returns         : nothing
327
#
328
sub ExamineThxPath
329
{
330
    my( $self, $platform ) = @_;
331
 
332
    my $dir = $self->{'base'} . '/thx';
333
    if ( -d $dir )
334
    {
335
        push @{$self->{'THXDIRS'}}, "/thx/$platform" if isUsefulDir( "$dir/$platform" );
336
        push @{$self->{'THXDIRS'}}, "/thx" if isUsefulDir( $dir );
337
    }
338
}
339
 
340
sub Cleanup
341
{
342
    my ($self) = shift;
343
 
344
    delete $self->{LIBEXAMINED};
345
    delete $self->{INCEXAMINED};
346
}
347
 
348
 
349
#-------------------------------------------------------------------------------
350
# Function        : GetBaseDir
351
#
352
# Description     : Return the base directory of a given package
353
#                   Simple getter function
354
#
355
# Inputs          : self
356
#                   path    - Optional path within package
357
#
358
# Returns         : The base directory of the package
359
#
360
sub GetBaseDir
361
{
362
    my ($self, $path) = @_;
363
    my $dir = $self->{'base'};
364
    $dir .= '/' . $path if ( $path );
365
    return $dir;
366
}
367
 
368
 
369
#-------------------------------------------------------------------------------
370
# Function        : SanityTest
371
#
372
# Description     : Examine all the packages used in the current build.pl
373
#                   and all the packages used to build them. Then generate
374
#                   warning if there are mismatches.
375
#
376
#                   All the data has been collected and stored within
377
#                   $DescPkgCache. This routine processes the data and
378
#                   constructs a data structure to locate packages with
379
#                   multiple versions.
380
#
381
#                   The project name is considered to be a part of the package
382
#                   name. Thus aaaa_11.22.33.mass is different to aaaa_11.22.33.syd
383
#
384
# Inputs          :
385
#
386
# Returns         :
387
#
388
my %package_list;
389
 
390
sub AddEntry
391
{
392
    my( $root, $rver, $rproj, $name, $version ) = @_;
393
    my $ver;
394
    my $proj;
395
 
396
    if ($version eq "!current") {
397
        $ver = "current";
398
        $proj = "";
399
    } else {
400
        $version =~ m~(.*)\.(.*?)$~;
401
        $ver = $1  || 'BadVer';
402
        $proj = $2 || 'BadProj';
403
    }
404
 
405
    ::UniquePush( \@{$package_list{"$name$;$proj"}{$ver}},  "${root}_${rver}.${rproj}");
406
}
407
 
408
sub SanityTest
409
{
410
    foreach my $package ( keys %DescPkgCache )
411
    {
412
        my $pptr = $DescPkgCache{$package};
413
        my $lver = $pptr->{'VERSION'};
414
           $lver .= '.' . $pptr->{'PROJ'} if ( $pptr->{'PROJ'} );
415
        AddEntry( $BUILDNAME_PACKAGE, $BUILDNAME_VERSION, $BUILDNAME_PROJECT, $pptr->{'NAME'}, $lver );
416
 
417
 
418
        foreach my $subpkg ( @{$pptr->{'PACKAGES'}} )
419
        {
420
            my $name = $subpkg->{name};
421
            my $ver = $subpkg->{version};
422
 
423
            AddEntry( $pptr->{'NAME'}, $pptr->{'VERSION'}, $pptr->{'PROJ'}, $name, $ver );
424
        }
425
    }
426
 
427
    #::DebugDumpData("XXX", \%package_list );
428
 
429
    #
430
    #   Detect and print warnings about multiple entries
431
    #
432
    my $first_found = 0;
433
    foreach my $pentry ( sort keys %package_list)
434
    {
435
        my @versions = keys %{$package_list{$pentry}};
436
 
437
        if ( $#versions > 0 )
438
        {
439
            ::Warning("Package mismatchs detected.") unless ( $first_found++ );
440
 
441
            my ($pname, $pproj) = split $;, $pentry ;
442
            foreach my $version ( @versions )
443
            {
444
                ::Warning("Package ${pname}_${version}.${pproj} used by:", @{$package_list{$pentry}{$version}});
445
            }
446
        }
447
 
448
    }
449
}
450
 
451
#-------------------------------------------------------------------------------
452
# Function        : Exists
453
#
454
# Description     : A class function to determine if a given package is known
455
#                   to the PackageEntry manager. Used to detect multiple package
456
#                   definitions.
457
#
458
#                   The test ignores package versions
459
#                   It is not possible to include different versions of the
460
#                   same package. The test ignores the project part of the
461
#                   version. This allows for
462
#                           sysbasetypes aa.bb.cc.mas and
463
#                           sysbasetypes xx.yy.zz.syd
464
#
465
# Inputs          : $name           - User package name
466
#                   $version        - User version ( with project )
467
#
468
# Returns         : True: Package exists
469
#
470
 
471
sub Exists
472
{
473
    my ($name, $version) = @_;
474
 
475
    $version =~ m~(\d+\.\d+\.\d+)\.(\w+)~ ;
476
    my $vnum = $1 || $version;
477
    my $proj = $2 || '';
478
 
479
    return exists( $PackageDefined{$name}{$proj} );
480
}
481
 
482
#-------------------------------------------------------------------------------
483
# Function        : GetPackageList
484
#
485
# Description     : A class function to return a list of packages
6177 dpurdie 486
#                   The list cannot be used directly. It is really a set of
227 dpurdie 487
#                   keys to an internal data structure.
488
#
489
#                   The result can be used to iterate over the list of packages
490
#                   using other functions.
491
#
492
# Inputs          : None
493
#
494
# Returns         : An array of package tags
495
#                   The array is ordered by package definition order
496
#
497
sub GetPackageList
498
{
499
    return @PackageList;
500
}
501
 
502
#-------------------------------------------------------------------------------
503
# Function        : GetPackageData
504
#
505
# Description     : A class function to return specific data for a given package
506
#
507
# Inputs          : $tag        - An iteration tag provided by GetPackageList()
508
#
509
# Returns         : A list of
510
#                       Package name
511
#                       Package version
512
#                       Package type : build or link
513
#
514
sub GetPackageData
515
{
516
    my ($tag) = @_;
517
    my $rec = $DescPkgCache{$tag};
518
    return $rec->{UNAME}, $rec->{UVERSION}, $rec->{type};
519
}
520
 
521
#-------------------------------------------------------------------------------
6192 dpurdie 522
# Function        : GetNameVersion
523
#
524
# Description     : Return a package name and version for display purposes
525
#
526
# Inputs          : $tag        - An iteration tag provided by GetPackageList()
527
#
528
# Returns         : A list of
529
#                       Package name
530
#                       Package version
531
#                       Package type : build or link
532
#
533
sub GetNameVersion
534
{
535
    my ($tag) = @_;
536
    my $rec = $DescPkgCache{$tag};
537
    return join( ' ', $rec->{NAME}, $rec->{VERSION_FULL} );
538
}
539
 
540
#-------------------------------------------------------------------------------
227 dpurdie 541
# Function        : GetPackageVersionList
542
#
543
# Description     : A class function to return a list of package names as used
544
#                   to generate version strings
545
#
546
#
547
# Inputs          : None
548
#
549
# Returns         : An array of version list entries
550
#                   Each element of the form: "name (version)"
551
#
552
sub GetPackageVersionList
553
{
554
    my @list;
555
    foreach my $tag ( @PackageList )
556
    {
557
        my $rec = $DescPkgCache{$tag};
558
        push @list, "$rec->{UNAME} ($rec->{UVERSION})";
559
    }
560
 
561
    return @list;
562
}
563
 
6276 dpurdie 564
#-------------------------------------------------------------------------------
565
# Function        : GetPackageSignature
566
#
567
# Description     : A class function to return a packages signature
568
#
569
#
570
# Inputs          : None
571
#
572
# Returns         : An array of version list entries
573
#                   Each element of the form: "name (version)"
574
#
575
sub GetPackageSignature
576
{
577
    my ($tag) = @_;
578
    my $rec = $DescPkgCache{$tag};
579
    return $rec->{PKGSIG};
580
}
6192 dpurdie 581
 
582
#-------------------------------------------------------------------------------
583
# Function        : Dump 
584
#
585
# Description     : Internal diagnostic tool
586
#                   Dumps internal data structures    
587
#
588
# Inputs          : None 
589
#
590
# Returns         : Nothing 
591
#
592
 
593
sub Dump
594
{
595
    ::DebugDumpData("PackageEntry",\%DescPkgCache);
596
}
597
 
227 dpurdie 598
### End of package: PackageEntry
599
 
600
1;
601