Subversion Repositories DevTools

Rev

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

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