Subversion Repositories DevTools

Rev

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

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