Subversion Repositories DevTools

Rev

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