Subversion Repositories DevTools

Rev

Rev 6276 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
227 dpurdie 1
########################################################################
6177 dpurdie 2
# COPYRIGHT - VIX IP PTY LTD ("VIX"). ALL RIGHTS RESERVED.
227 dpurdie 3
#
4
# Module name   : jats.sh
5
# Module type   : Makefile system
6
# Compiler(s)   : n/a
7
# Environment(s): jats build system
8
#
9
# Description   : Provide access to information from the build.pl file as parsed
10
#                 by JATS. This is more complete than the parser in the
11
#                 "BuildFile.pm"
12
#
13
#                 The purpose of this module is to provide an interface
14
#                 between (essentially) internal data structures and user
15
#                 scripts that need to access the data. These are primarily
16
#                 deployment scripts.
17
#
18
#                 The 'All' tag is used for backward compatabilty. It simply
19
#                 exports all the known data structures. NOT to be used by new
20
#                 code.
21
#
22
#
23
#
24
# Interface     : ReadBuildConfig           - Initialise module
25
#                 getPlatformParts          - Get a list of Platform parts
6133 dpurdie 26
#                 
27
#                 PackageEntry - Internal class
28
#                   getUnifiedName
29
#                   getBase
30
#                   getName
31
#                   getVersion
32
#                   getType
33
#                   getDir
34
#                   getLibDirs
35
#                   getIncDirs
227 dpurdie 36
#
37
#......................................................................#
38
 
255 dpurdie 39
require 5.006_001;
227 dpurdie 40
use strict;
41
use warnings;
42
 
43
#===============================================================================
44
package ReadBuildConfig;
45
use JatsError;
46
use JatsMakeInfo qw(:basic);
4324 dpurdie 47
use FileUtils;
227 dpurdie 48
 
49
# automatically export what we need into namespace of caller.
50
use Exporter();
51
our (@ISA, @EXPORT, %EXPORT_TAGS, @EXPORT_OK);
52
@ISA         = qw(Exporter);
53
@EXPORT      = qw(  ReadBuildConfig
54
                    getPlatformParts
55
                    getPackagePaths
271 dpurdie 56
                    getPackageList
4324 dpurdie 57
                    getToolInfo
6177 dpurdie 58
                    testToolInfo
6133 dpurdie 59
                    getAliases
6276 dpurdie 60
                    isGenericBuild
227 dpurdie 61
                );
62
@EXPORT_OK =  qw(   $InterfaceVersion
63
                    $ScmBuildMachType
64
                    $ScmInterfaceVersion
65
                    $ScmBuildName
66
                    $ScmBuildPackage
67
                    $ScmBuildVersion
6511 dpurdie 68
                    $ScmBuildBaseVersion
227 dpurdie 69
                    $ScmBuildProject
70
                    $ScmBuildVersionFull
71
                    $ScmBuildPreviousVersion
72
                    $ScmSrcDir
73
                    $ScmLocal
74
                    $ScmDeploymentPatch
75
                    $ScmBuildSrc
76
                    $ScmExpert
261 dpurdie 77
                    $ScmAll
4003 dpurdie 78
                    $ScmNoBuild
6177 dpurdie 79
                    $ScmBuildUuid
227 dpurdie 80
                    %ScmBuildAliases
81
                    %ScmBuildProducts
82
                    %ScmBuildPlatforms
6276 dpurdie 83
                    %ScmBuildMatrix
227 dpurdie 84
                    %ScmBuildPkgRules
85
                    @BUILDPLATFORMS
86
                    @DEFBUILDPLATFORMS
87
                    @BUILDTOOLSPATH
88
                    %BUILDPLATFORM_PARTS
89
                    %BUILDINFO
247 dpurdie 90
                    %BUILD_KNOWNFILES
227 dpurdie 91
                );
92
 
93
%EXPORT_TAGS = (All => [@EXPORT, @EXPORT_OK]);
94
 
95
#-------------------------------------------------------------------------------
96
#   Global variables
97
#
98
 
99
my $interface;
100
my $platform;
101
 
102
#
103
#   The $InterfaceVersion value is manually maintained
104
#   The integer part should be changed to indicate a incompatible change
105
#   to the JATS files created within the interface directory
106
#
107
#   $InterfaceVersion is treated as a float. The fractional part can be
108
#   used to indicate minor changes to the file format.
109
#
110
our $InterfaceVersion       = "2.0";            # Change will issue error message
111
 
112
#
113
#   The following varaibles are "read" in from the build.cfg file
114
#   In order to access simply access we need to declare them
115
#
116
our %BUILDINFO;
117
our %BUILDPLATFORM_PARTS;
118
our $ScmInterfaceVersion;
119
our %ScmBuildPkgRules;
120
our $ScmBuildMachType;
6276 dpurdie 121
our %ScmBuildMatrix; 
227 dpurdie 122
 
123
#-------------------------------------------------------------------------------
124
# Function        : ReadBuildConfig
125
#
126
# Description     : Read in the build config information
127
#                   Read in build.cfg
128
#
129
# Inputs          : $interface              - Path to the interface directory
130
#                   $platform               - Platform being processed
131
#
132
# Returns         : Nothing
133
#
134
sub ReadBuildConfig
135
{
136
    $interface = shift;
137
    $platform = shift;
138
 
139
    my $no_test;
140
    foreach  ( @_ )
141
    {
142
        if ( m/^--NoTest/i ) {
143
            $no_test = 1;
144
        } else {
145
            Warning ("ReadBuildConfig, Unknown option: $_");
146
        }
147
    }
148
 
149
    Debug("BuildConfig::Reading config, $interface");
150
    my $cfgfile = "$interface/build.cfg";
151
    Error ("JATS internal file missing. Rebuild required",
152
           "BuildConfig: Cannot find file: $cfgfile" ) unless ( -f $cfgfile );
153
 
154
    #
155
    #   Include the build.cfg data
156
    #
157
    require ( $cfgfile );
158
 
159
    #
160
    #   Ensure that the version of the interface files can be consumed
161
    #   The $ScmInterfaceVersion is a written copy of $InterfaceVersion
162
    #
163
    #   Allow build.cfg files that do not have a ScmInterfaceVersion
164
    #   Assume that these are at version 1.0.
165
    #
166
    $ScmInterfaceVersion = '1.0' unless ( $ScmInterfaceVersion );
167
    Debug ("ReadBuildConfig: Version: $ScmInterfaceVersion, Need: $InterfaceVersion");
168
    if ( int($ScmInterfaceVersion) != int($InterfaceVersion)  )
169
    {
170
        Error ("JATS interface files are not compatible with this version of JATS",
171
               "Rebuild required.",
172
               "Current Interface Version: $ScmInterfaceVersion",
173
               "JATS Interface Version   : $InterfaceVersion" );
174
    }
175
 
176
    #
177
    #   Ensure that this config file is designed for this machine type
178
    #   At make-time this test may not be valid. It should have been
179
    #   validated before make-time.
180
    #
181
    TestMachType ($ScmBuildMachType, "build.cfg") unless $no_test;
182
 
183
    #
184
    #   Remove some unused data
185
    #   Reduces the size of Makefile.cfg. Speeds up writting
186
    #
187
    if ( $platform )
188
    {
189
        for (keys %::ScmBuildPlatforms)
190
        {
191
            next if ($_ eq $platform );
192
            delete ($::BUILDPLATFORM_PARTS{$_} );
193
            delete ($::BUILDINFO{$_} );
194
            delete ($::ScmBuildPkgRules{$_} );
195
        }
196
    }
197
 
198
    #   dump
199
    #
200
    Debug( "Aliases:" );
369 dpurdie 201
    if ( ! (%::ScmBuildAliases) ) {
227 dpurdie 202
        Debug( "  undefined" );
203
 
204
    } else {
205
        foreach my $key (keys %::ScmBuildAliases) {
206
            my( @value ) = split( ' ', $::ScmBuildAliases{ $key } );
207
            Debug( " $key\t= @value" );
208
        }
209
    }
210
 
211
    Debug( "Products:" );
369 dpurdie 212
    if ( ! (%::ScmBuildProducts) ) {
227 dpurdie 213
        Debug( "  undefined" );
214
 
215
    } else {
216
        foreach my $key (keys %::ScmBuildProducts) {
217
            my( @value ) = split( ',', $::ScmBuildProducts{ $key } );
218
            Debug( " $key\t= @value" );
219
        }
220
    }
221
 
222
    Debug( "Platforms:" );
369 dpurdie 223
    if ( ! (%::ScmBuildPlatforms) ) {
227 dpurdie 224
        Debug( "  undefined" );
225
 
226
    } else {
227
        foreach my $key (keys %::ScmBuildPlatforms) {
228
            my( @args ) = split( /$;/, $::ScmBuildPlatforms{ $key } );
229
            Debug( " $key\t= @args" );
230
        }
231
    }
232
}
233
 
234
#-------------------------------------------------------------------------------
6276 dpurdie 235
# Function        : isGenericBuild 
236
#
237
# Description     : Determine if this is a 'GENERIC' build
238
#                   ie: can be built on ANY build machine
239
#
240
# Inputs          : 
241
#
242
# Returns         : TRUE - Is generic
243
#
244
sub isGenericBuild
245
{
246
    return exists $ScmBuildMatrix{'GENERIC'} ? 1 : 0;
247
}
248
 
249
#-------------------------------------------------------------------------------
6133 dpurdie 250
# Function        : getAliases 
251
#
252
# Description     : Return a list of aliases for the current platform
253
#
254
# Inputs          : 
255
#
256
# Returns         : A list of aliases
257
#
258
sub getAliases
259
{
260
    Error ("BuildConfig:getAliases. Not initialised") unless ( $platform );
261
    #
262
    #   Determine the aliases for this target
263
    #       The alias list includes the actual target too
264
    #
265
    my @AliasList;
266
    push @AliasList, $platform;
267
 
268
    if ( exists( $BUILDINFO{$platform}{'ALIAS'} ))
269
    {
270
        push @AliasList, $BUILDINFO{$platform}{'ALIAS'};
271
    }
272
 
273
    if ( exists( $BUILDINFO{$platform}{'USERALIAS'} ))
274
    {
275
        push @AliasList, @{$BUILDINFO{$platform}{'USERALIAS'}};
276
    }
277
 
278
    return @AliasList;
279
}
280
 
281
 
282
#-------------------------------------------------------------------------------
227 dpurdie 283
# Function        : getPlatformParts
284
#
285
# Description     : return a list of platform parts
286
#
287
# Inputs          : None
288
#
289
# Returns         : A list of platform parts to search in the interface
290
#                   directory, local directory or other
291
#
292
sub getPlatformParts
293
{
294
    Error ("BuildConfig. Not initialised") unless ( $platform );
295
    return @{$BUILDINFO{$platform}{PARTS}};
296
}
297
 
298
#-------------------------------------------------------------------------------
299
# Function        : getPackagePaths
300
#
301
# Description     : Return a list of all packages
302
#                   LinkPkgarchive packages will be provided as is
303
#                   BuildPkgArchive packages will be provided as a single
304
#                   reference to the interface directory
305
#
306
# Inputs          : Options
307
#                       --Interface=xxxx            Path to the interface dir
308
#                                                   If provided, then the path
309
#                                                   will be used for the first
310
#                                                   BuildPkgArchive
311
#                       --All                       All paths
312
#                       --Tools                     All Tools Paths
313
#                       --Gbe                       All Gbe paths
314
#
315
# Returns         : An array of paths
316
#
317
sub getPackagePaths
318
{
319
    Error ("BuildConfig. Not initialised") unless ( $platform );
320
 
321
    my $interface;
322
    my $all;
323
    my $need;
324
    my @result;
325
 
326
    #
327
    #   Parse Options
328
    #
329
    foreach ( @_ )
330
    {
331
        if ( m~^--Interface=(.+)~ ) {
332
            $interface = $1;
333
        } elsif ( m~^--All~ ) {
334
            $all = 1;
335
        } elsif ( m~^--Tools~ ) {
336
            $need = 'TOOLDIRS';
337
        } elsif ( m~^--Gbe~ ) {
338
            $need = 'CFGDIR';
339
        } else {
340
            Error ("BuildConfig. Unknown Option: $_");
341
        }
342
    }
343
 
344
    #
311 dpurdie 345
    #   Locate required entries
227 dpurdie 346
    #
347
    for my $entry (@{$ScmBuildPkgRules{$platform} })
348
    {
349
        #
350
        #   Do we need this entry
351
        #   Select tools and gbe entries
352
        #
353
        my @subdirs = '/';
354
        if ( $need )
355
        {
356
            next unless ( exists ($entry->{$need} ) );
357
            my $subdir = $entry->{$need};
358
            if ( ref($subdir) eq 'ARRAY' ) {
359
                @subdirs = @{$subdir};
360
            } else {
361
                @subdirs = $subdir;
362
            }
363
        }
364
 
365
        #
311 dpurdie 366
        #   Skip the Pseudo INTERFACE package if we are processing all packages
367
        #   Skip BuildPkgArchives if we aren't processing all
227 dpurdie 368
        #
311 dpurdie 369
        next if ( ($entry->{'TYPE'} eq 'interface') && $all );
370
        next if ( ($entry->{'TYPE'} eq 'build') && !$all );
371
 
372
        #
373
        #   Select appropriate root
374
        #       Use provided interface path - not too sure why
375
        #       Should be able to simplify this
376
        #
377
        my $dir = $entry->{'ROOT'};
378
        $dir = $interface if ( $entry->{'TYPE'} eq 'interface' );
379
 
380
        foreach my $subdir ( @subdirs )
227 dpurdie 381
        {
311 dpurdie 382
            my $dir = $entry->{'ROOT'} . $subdir;
383
            $dir =~ s~/+~/~g;
384
            $dir =~ s~/+$~~g;
385
            push @result, $dir;
227 dpurdie 386
        }
387
    }
388
 
389
    return @result;
390
}
391
 
271 dpurdie 392
#-------------------------------------------------------------------------------
393
# Function        : getPackageList
394
#
395
# Description     : Returns a list of package entries
4324 dpurdie 396
#                   Only real use of the returned values is to iterate over it
397
#                   and pass the values into other functions within this
271 dpurdie 398
#                   class.
399
#
400
# Inputs          : Nothing
401
#
402
# Returns         : A list of refs to package data
403
#
404
sub getPackageList
405
{
406
    Error ("BuildConfig. Not initialised") unless ( $platform );
407
    my @result;
408
 
409
    foreach ( @ {$ScmBuildPkgRules{$platform} } )
410
    {
411
#        my %self;
412
#        $self{DATA} = $_;
413
        push @result, bless $_, "PackageEntry";
414
    }
415
    return ( @result );
416
}
417
 
4324 dpurdie 418
#-------------------------------------------------------------------------------
6177 dpurdie 419
# Function        : testToolInfo 
4324 dpurdie 420
#
6177 dpurdie 421
# Description     : Test to see if suitable toolInfo exists
422
#                   May be used if the need for the toolInfo is optional
4324 dpurdie 423
#
6177 dpurdie 424
# Inputs          : $toolname       - Tool to locate
425
#                   $error          - True: Error on not found
4324 dpurdie 426
#
6177 dpurdie 427
# Returns         : undefined       - No tool located
428
#                   refToToolEntry  - Used internally
4324 dpurdie 429
#
6177 dpurdie 430
sub testToolInfo
4324 dpurdie 431
{
6177 dpurdie 432
    my ($toolname, $error) = @_;
4324 dpurdie 433
    my $toolroot;
434
    my $toolinfo;
435
    my $pentry;
436
    my @searchPath;
437
 
438
    foreach my $entry ( getPackageList() )
439
    {
440
        my $path = $entry->getBase(2);
441
        Verbose("getToolInfo: $path");
442
        #   Generic
443
        $toolinfo = catdir($path, 'gbe', 'INFO', 'info.' . $toolname . '.generic');
444
        push @searchPath, $toolinfo;
445
        if ( -f $toolinfo )
446
        {
447
            $toolroot = $path;
448
            $pentry = $entry;
449
            last;
450
        }
451
        #   Machine specific
452
        $toolinfo = catdir($path, 'gbe', 'INFO', 'info.' . $toolname . '.'. $ENV{GBE_HOSTMACH});
453
        push @searchPath, $toolinfo;
454
        if ( -f $toolinfo )
455
        {
456
            $toolroot = $path;
457
            $pentry = $entry;
458
            last;
459
        }
460
    }
6177 dpurdie 461
 
462
    unless (defined $toolroot)
4324 dpurdie 463
    {
6177 dpurdie 464
        #   Didn't find the required tool
465
        Error ("Cannot find required tool in any package: $toolname", "Search Path:", @searchPath) if ($error );
466
        return undef ;
467
    }
468
 
469
    #
470
    #   Return user info
471
    #
472
    return ($pentry, $toolroot, $toolinfo) if (wantarray);
473
    return $pentry;
474
}
475
 
476
 
477
#-------------------------------------------------------------------------------
478
# Function        : getToolInfo 
479
#
480
# Description     : Locate and load the tool information for the named tool
481
#
482
# Inputs          : $toolname           - tool to locate
483
#                   ...                 - Optional,Names of fields to expect in the package
484
#                                         If any of the required fields ar missing an error
485
#                                         will be reported
486
#
487
# Returns         : A hash of Tool info
488
#
489
sub getToolInfo
490
{
491
    my ($toolname, @fnames) = @_;
492
    my %data;
493
 
494
    #
495
    #   Check existence and get essential information
496
    #       Will not return if not found
497
    #
498
    my ($pentry, $toolroot, $toolinfo) = testToolInfo ($toolname, 1);
499
 
500
    open (my $DATA, '<', $toolinfo ) || Error("Cannot open tool info file. $!", "File: $toolinfo");
501
    while ( <$DATA> )
502
    {
503
        $_ =~ s~\s+$~~;
504
        next if ( m~^#~ );
505
        next if length($_) < 1;
506
        m~(.*?)\s*=\s*(.*)~;
507
        $data{$1} = $2;
508
    }
509
    close $DATA;
510
    $data{PKGBASE} = $toolroot;
511
    $data{PKGENTRY} = $pentry;
4324 dpurdie 512
#DebugDumpData("Data", \%data);
513
 
6177 dpurdie 514
    #
515
    #   Ensure that the required fields are in the info file
516
    #   These will be a mix of mandatory and user fields
517
    #
518
    my @missing;
519
    for my $fname ('TOOLNAME','TOOLROOT', @fnames)
520
    {
521
        next if defined $data{$fname};
522
        push @missing, $fname;
4324 dpurdie 523
    }
6177 dpurdie 524
    if (@missing)
525
    {
526
        Error("Tool Package '$toolname' is missing required fields:", @missing);
527
    }
528
    return \%data;
4324 dpurdie 529
}
530
 
531
 
271 dpurdie 532
################################################################################
533
#   PackageEntry
534
################################################################################
535
#
536
#   A class to access the data embedded into $ScmBuildPkgRules
537
#   Use a class interface to abstract the data
538
#
539
package PackageEntry;
540
 
541
#-------------------------------------------------------------------------------
542
# Function        : dump
543
#
544
# Description     : Diagnostic Dump of the body of the package entry
545
#
546
# Inputs          : None
547
#
548
# Returns         : None
549
#
550
sub dump
551
{
552
    my $self = shift;
553
    ::DebugDumpData("PackageEntry", $self );
554
}
555
 
556
#-------------------------------------------------------------------------------
5411 dpurdie 557
# Function        : getUnifiedName 
558
#
559
# Description     : Return a Package Name based on PackageName and project suffix
560
#                   Package Name is cleaned up a bit
561
#                       Replace non-alphanumenrics with a '_'
562
#                       Converted to upper case 
563
#
564
# Inputs          : $self
565
#                   $prefix         - Optional Prefix 
566
#                   $suffix         - Optional Suffix 
567
#
568
# Returns         : String
569
#
570
sub getUnifiedName
571
{
572
    my ($self,$prefix,$suffix) = @_;
573
 
574
    my $name = $prefix || '';
575
    $name .= $self->{'DNAME'};
576
    $name .= '_' . $self->{'DPROJ'} if $self->{'DPROJ'};
577
    $name .= $suffix || '';
578
 
579
    $name =~ s~\W~_~g; 
580
    $name =~ s~-~_~g; 
581
    $name =~ tr~_~_~s;
582
    $name = uc $name;
583
    return $name;
584
}
585
 
586
 
587
#-------------------------------------------------------------------------------
271 dpurdie 588
# Function        : getBase
589
#
590
# Description     : Determine the base directory of the package
591
#
592
# Inputs          : $self                   - Class Ref
593
#                   $type                   - 0: Empty
594
#                                             1: abs dpkg_archive
595
#                                             2: May be in the interface
311 dpurdie 596
#                                             3: Interface, LinkPkgs
271 dpurdie 597
#
598
# Returns         : As above
599
#
600
sub getBase
601
{
602
    my ($self, $type ) = @_;
6177 dpurdie 603
    ::Error ("Internal: PackageEntry::getBase called without 'type' argument") unless defined $type;
371 dpurdie 604
 
271 dpurdie 605
    if ( $type == 1 ) {
606
        return $self->{ROOT};
607
    } elsif ( $type == 2 ) {
311 dpurdie 608
        if ( $self->{'TYPE'} eq 'build' ) {
609
            return $interface;
610
        } else {
271 dpurdie 611
            return $self->{ROOT};
612
        }
311 dpurdie 613
    } elsif ( $type == 3 ) {
614
        return if ( $self->{'TYPE'} eq 'build' );
371 dpurdie 615
        return $self->{ROOT};
271 dpurdie 616
    } else  {
617
        return '';
618
    }
619
}
620
 
621
#-------------------------------------------------------------------------------
6133 dpurdie 622
# Function        : getXxxx 
623
#
624
# Description     : Various getters
625
#
626
# Inputs          : $self - Reference to the class 
627
#
628
# Returns         : Value
629
#
630
 
631
sub getName
632
{
633
    my ($self) = @_;
634
    return $self->{NAME};
635
}
636
 
637
sub getVersion
638
{
639
    my ($self) = @_;
640
    return $self->{VERSION};
641
}
642
 
643
sub getType
644
{
645
    my ($self) = @_;
646
    return $self->{TYPE};
647
}
648
 
649
#
650
#   Returns the location of the package.
651
#       This will be a ref into the package store
652
#       Used only if access to dpkg_archive is needed
653
#       Only useful if TYPE is build or link
654
#
655
sub getDir
656
{
657
    my ($self) = @_;
658
    return $self->{ROOT};
659
}
660
 
661
#-------------------------------------------------------------------------------
271 dpurdie 662
# Function        : getLibDirs
663
#
664
# Description     : Return an array of library directories
665
#
666
# Inputs          : $self                   - Class ref
667
#                   $type                   - 0 : Relative to base of the package
668
#                                             1 : abs to the dpkg_archive package
669
#                                             2 : abs to the interface
6133 dpurdie 670
#                                             3 : Interface, LinkPkgs
271 dpurdie 671
#
672
# Returns         : An array
673
#
674
sub getLibDirs
675
{
676
    my ($self, $type ) = @_;
677
    my @result;
678
    my $prefix = getBase( $self, $type );
679
 
680
    foreach ( @{$self->{PLIBDIRS}} )
681
    {
682
        push @result, $prefix . $_;
683
    }
684
    return @result;
685
}
686
 
687
#-------------------------------------------------------------------------------
688
# Function        : getIncDirs
689
#
690
# Description     : Return an array of include directories
691
#
692
# Inputs          : $self                   - Class ref
693
#                   $type                   - 0 : Relative to base of the package
694
#                                             1 : abs to the dpkg_archive package
695
#                                             2 : abs to the interface
311 dpurdie 696
#                                             3: Interface, LinkPkgs
271 dpurdie 697
#
698
# Returns         : An array
699
#
700
sub getIncDirs
701
{
702
    my ($self, $type ) = @_;
703
    my @result;
704
    my $prefix = getBase( $self, $type );
705
 
706
    foreach ( @{$self->{PINCDIRS}} )
707
    {
708
        push @result, $prefix . $_;
709
    }
710
    return @result;
711
}
712
 
227 dpurdie 713
#------------------------------------------------------------------------------
714
1;