Subversion Repositories DevTools

Rev

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