Subversion Repositories DevTools

Rev

Rev 6276 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
3967 dpurdie 1
########################################################################
6177 dpurdie 2
# COPYRIGHT - VIX IP PTY LTD ("VIX"). ALL RIGHTS RESERVED.
227 dpurdie 3
#
4
# Module name   : common.pl
5
# Module type   : Makefile system
3967 dpurdie 6
# Compiler(s)   : Perl
7
# Environment(s): jats
227 dpurdie 8
#
9
# Description   : Some function common to build and makefile processing tools.
10
#
3967 dpurdie 11
#......................................................................#
227 dpurdie 12
 
13
use strict;
14
use warnings;
15
use JatsError;
16
use JatsSystem;
17
use ConfigurationFile;
18
use FileUtils;
19
use ArrayHashUtils;
20
use ReadBuildConfig qw(:All);
21
use JatsMakeConfig;
22
 
23
our $CommonVersion          = "1.03";
24
 
25
our $CurrentYear            = "";
26
our $CurrentTime            = "";
27
our $CurrentDate            = "";
28
our $All;
29
 
30
our @BUILD_ACTIVEPLATFORMS  = ();               # Array of active platforms
31
our @DEFBUILDPLATFORMS = ();
263 dpurdie 32
our $GBE_TOOLS;
7447 dpurdie 33
our $GBE_OPTS;
34
our $LegacyMode = 0;                            # Indicates either ABT or a LEGACY build
227 dpurdie 35
 
36
#-------------------------------------------------------------------------------
37
# Function        : CommonInit
38
#
39
# Description     : Initialisation routine for this common code
40
#                   The function MUST be called after the package has been
41
#                   loaded with a "require" statement.
42
#
43
#
44
# Inputs          : $who            - Name of the package using the routines
45
#                                     Used for error reporting
46
#
47
# Returns         : Nothing
48
#
49
sub CommonInit
50
{
51
    my( $who ) = @_;
6198 dpurdie 52
    ErrorConfig( 'name' => $who );
227 dpurdie 53
    SystemConfig ('UseShell' => 1 );
54
 
6198 dpurdie 55
    Debug( "Common ($who)" );
227 dpurdie 56
    Debug( "version:   $::CommonVersion" );
57
    Debug( "Debug:     $::ScmDebug" );
58
    Debug( "Verbose:   $::ScmVerbose" );
59
 
5867 dpurdie 60
    #   Envars used by this module
61
    EnvImportOptional ( 'GBE_ABT' );                # optional ABT flags          
7447 dpurdie 62
    EnvImportOptional ( 'GBE_OPTS', '' );           # optional OPTS flags
63
                                                    # 
64
    $LegacyMode = $::GBE_ABT || $::GBE_OPTS =~ m/LEGACY/i;          
5867 dpurdie 65
 
227 dpurdie 66
    #
67
    #   Init the FileUtils package
68
    #   Sets various globals used throughout the program
69
    #
70
    InitFileUtils();
71
 
72
    #
73
    #   Init global time variables
74
    #
6198 dpurdie 75
    $::ComonInitDone = 1;
227 dpurdie 76
    $::CurrentTime = localtime;
77
 
78
    my ($sec, $min, $hour, $mday, $mon, $year) = localtime();
79
    $::CurrentYear = 1900 + $year;
80
    $::CurrentDate                              # eg. 13/10/86
81
        = sprintf ("%02u/%02u/%02u", $mday, $mon+1, $year % 100);
82
}
83
 
84
#-------------------------------------------------------------------------------
85
# Function        : AUTOLOAD
86
#
87
# Description     : Intercept bad user directives and issue a nice error message
88
#                   This is a simple routine to report unknown user directives
89
#                   It does not attempt to distinguish between user errors and
90
#                   programming errors. It assumes that the program has been
91
#                   tested. The function simply report filename and line number
92
#                   of the bad directive.
93
#
94
# Inputs          : Original function arguments ( not used )
95
#
96
# Returns         : This function does not return
97
#
98
sub AUTOLOAD
99
{
283 dpurdie 100
    my $args = JatsError::ArgsToString( \@_);
227 dpurdie 101
    my $fname = $::AUTOLOAD;
102
    $fname =~ s~^\w+::~~;
103
    my ($package, $filename, $line) = caller;
104
 
105
    Error ("Directive not known or not allowed in this context: $fname",
283 dpurdie 106
           "Directive: $fname( $args );",
227 dpurdie 107
           "File: $filename, Line: $line" );
108
}
109
 
110
#-------------------------------------------------------------------------------
5867 dpurdie 111
# Function        : abtWarning 
112
#
113
# Description     : User Error, Build System Warning
114
#                   Used to tighten up builds while retaining BuildSystem compatability
115
#
116
#                   ABT Mode is a bit more forgiving, but only for backward compatability
117
#                   Otherwise force users to fix the build.pl and makefile.pl files.
118
#
119
# Inputs          : $mode           - True.   Exit if Error
120
#                                     False.  Delay error exit. Use must use ErrorDoExit() 
121
#                   $msg            - Message to display
122
#                   @msgbits        - Other message arguments
123
#
124
# Returns         : May not return
125
#
126
sub abtWarning
127
{
128
    my ($mode, $msg, @msgbits) = @_;
7447 dpurdie 129
    if ( $LegacyMode ) {
130
        Warning( $msg . ' -- ignored in ABT/LEGACY Mode',  @msgbits);
5867 dpurdie 131
        return;
132
    }
133
    ReportError($msg, @msgbits);
134
    ErrorDoExit() if $mode;
135
}
136
 
137
#-------------------------------------------------------------------------------
227 dpurdie 138
# Function        : ConfigLoad
139
#
140
# Description     : Loads the global configuration details
141
#                   Details are held within the interface directory in "build.cfg"
142
#
143
# Inputs          : None
144
#
145
# Returns         : Nothing
146
#                   Will populate the global environment space with the contents
147
#                   of the build.cfg file. These variables may need to be access
148
#                   with the :: syntax ($::Variable)
149
#
150
#                   This function will remove lumps of the configuration that
151
#                   are not needed by the current platform simply to reduce the
152
#                   data retaied in other config files.
153
#
154
#
155
sub ConfigLoad
156
{
157
   ReadBuildConfig("$::ScmRoot/$::ScmInterface", $::ScmPlatform );
158
}
159
 
6276 dpurdie 160
#-------------------------------------------------------------------------------
161
# Function        : ExpandPlatforms 
162
#
163
# Description     : Expand a user provided platform list and resolve aliases
164
#                   Note: Need to avoid recusion
165
#                         ie: Alias AAA -> BBB, CCC, AAA is allowed
166
#                         because alias have already been expanded
167
#                         
168
#                         Use. The SOLARIS alias expands to several alias including SOLARIS
169
#                              The expanded SOLARIS is actually a PLATFORM
170
#                              I know it sucks - backward compatability always does
171
#                              
172
#                   Alias information will come from one of two places
173
#
174
# Inputs          : A list of platforms, aliases and options
175
#
176
# Returns         : A list of platforms 
177
#
227 dpurdie 178
 
179
sub ExpandPlatforms
180
{
181
    our( @_expandarg ) = @_;
6276 dpurdie 182
    our @_expandresult = ();
183
    our $_expandnest = 0;
227 dpurdie 184
 
6276 dpurdie 185
    #
186
    #   Use one of
187
    #       BUILDALIAS - as setup by buildfile.pl
188
    #       ScmBuildAliases - makelib.pl and makelib.pl2 
189
    #
190
    our %_Aliases = %::ScmBuildAliases ? %::ScmBuildAliases : %::BUILDALIAS;  
227 dpurdie 191
 
192
    Debug3( "ExpandPlatforms(@_)" );
6276 dpurdie 193
#    DebugTraceBack( "ExpandPlatforms(@_)" );
194
#    DebugDumpData("Aliases",\%_Aliases);
227 dpurdie 195
 
196
    sub ExpandPlatform
197
    {
198
        sub ExpandAlias
199
        {
200
            my( $key ) = @_;
201
 
202
 
6276 dpurdie 203
            return $key                     # argument || no aliases
204
                if ( $key =~ /^--/ || !(%_Aliases) );
227 dpurdie 205
 
6276 dpurdie 206
            return ExpandPlatform( split( ' ', $_Aliases{ $key } ) )
207
                if ( exists $_Aliases{ $key } );
208
 
227 dpurdie 209
            return $key;
210
        }
211
 
212
        sub ExpandPush
213
        {
214
            my( $pResult, $operator, $pPlatforms, @arguments ) = @_;
215
 
216
            foreach my $platform ( @$pPlatforms )
217
            {                                   # unfold arguments
218
                push( @$pResult, $operator.$platform );
219
                next if ( $platform =~ /^--/ );
220
                push( @$pResult, @arguments );
221
            }
222
        }
223
 
224
        Error( "ExpandPlatforms( @_expandarg ) nesting error.",
225
               "",
226
               "Check for recursive definitions within the follow directives",
227
               "       - BuildAlias and BuildProduct."
228
             ) if ( $_expandnest++ > 42 );
229
 
230
        my( @result, $operator, @platforms, @arguments ) = ();
231
 
232
        Debug3( "  +$_expandnest: @_ " );
233
 
234
        foreach my $arg ( @_ ) {
235
            if ( $arg =~ /^--/ ) {              # argument, accumulate
236
                push( @arguments, $arg );
237
 
238
            } else {                            # group, product or platform
239
                ExpandPush( \@result, $operator, \@platforms, @arguments );
240
 
241
                if ( ($operator = substr($arg, 0, 1)) eq "!" ) {
242
                    @platforms = ExpandAlias( substr($arg, 1) );
243
                } else {
244
                    $operator = "";
245
                    @platforms = ExpandAlias( $arg );
246
                }
247
                @arguments = ();
248
            }
249
        }
250
        ExpandPush( \@result, $operator, \@platforms, @arguments );
251
 
252
        $_expandnest--;
253
        Debug3( "  -$_expandnest: @result" );
254
        return @result;
255
    }
256
 
257
    ############################################################################
258
    #   Function body
259
    #
260
 
261
    foreach (@_expandarg) {                      # break out embedded args
262
        if ( /^--/ ) {
263
            push @_expandresult, $_;
264
 
265
        } else {
266
            push @_expandresult, split( ',', $_ );
267
        }
268
    }
269
 
270
    @_expandresult = ExpandPlatform( @_expandresult );
271
    Debug2( "ExpandPlatforms(@_expandarg) = @_expandresult" );
272
    return @_expandresult;
273
}
274
 
275
#-------------------------------------------------------------------------------
276
# Function        : Exists( $path, $name, $msg, [@paths] ) ---
277
#
278
# Description     : Case insensitive 'exists'.
279
#
280
# Inputs          :
281
#       $path       Represents either the absolute path of the file
282
#                   named 'name' in the case of @path being an empty
283
#                   list, or the subdir appended to each entry
284
#                   contained within the @paths list.
285
#
286
#       $name       The file name
287
#
288
#       $desc       Text used to describe the file upon the image
289
#                   not being found.
290
#
291
#       @paths      Optional list of paths to be searched.
292
#
293
# Returns         : Full path of resolved filename, otherwise nothing.
294
#
295
#   Examples:
296
#
297
#       a)  Exists( "/mypath", "Myfile", "stuff" );
298
#
299
#           Resolve the name of the file called "myfile" within the
300
#           directory "/mypath", using the following matching order
6276 dpurdie 301
#           
302
#               1.  "/mypath/Myfile". As supplied.
303
#               2.  Scan "/mypath" for all files and perform a case 
304
#                   insensitive comparison for MYFILE.
227 dpurdie 305
#
306
#           Upon being not found displays the message
307
#
308
#               "stuff (/mypath/Myfile) not found".
309
#
310
#       b)  @paths = ( '/dir1', '/dir2' );
311
#           Exists( "cfg", "Myfile", "stuff", @paths );
312
#
313
#           Resolve the name of the file called "Myfile" within the
314
#           set of directories "/dir1/cfg/" and "/dir2/cfg/", using
315
#           the following matching order:
316
#
317
#               1.  "/dir1/cfg/Myfile".
6276 dpurdie 318
#               2.  "/dir1/cfg/<Scan for MYFILE>".
319
#               3.  "/dir2/cfg/Myfile".
320
#               4.  "/dir2/cfg/<Scan for MYFILE>".
227 dpurdie 321
#
322
#           Upon being not found displays the message
323
#
324
#               "stuff (cfg/Myfile) not found".
325
#
6276 dpurdie 326
my %ExistsDirCache;
227 dpurdie 327
sub Exists
328
{
329
    my( $path, $name, $msg, @paths ) = @_;
6276 dpurdie 330
    my $file;
331
    my $ucName = uc($name);
227 dpurdie 332
    Debug2 "Searching for $path/$name (" . ($msg || '') . ")";
333
    Debug2 " using @paths" if ( @paths );
334
 
6276 dpurdie 335
    #
336
    #   Convert the two call methods into a common method
337
    #   Convert path with empty @paths into an array of paths with an empty 'path'
338
    #
339
    unless (@paths) {
340
        push @paths, $path;
341
        $path = '';
227 dpurdie 342
    }
343
 
6276 dpurdie 344
    SCANPATHS:
345
    foreach my $thisPath ( @paths) {
227 dpurdie 346
 
6276 dpurdie 347
        my $curPath = $thisPath . '/' . $path . '/';
348
        $curPath =~ s~//$~/~;
227 dpurdie 349
 
6276 dpurdie 350
        #
351
        #   Try exact file name first - should work most of the time
352
        #
353
        $file = $curPath . $name; 
227 dpurdie 354
        Debug2 " -> $file";
6276 dpurdie 355
        last SCANPATHS if ( -f $file );
227 dpurdie 356
 
6276 dpurdie 357
        #
358
        #   Scan all files in the directory for the first
359
        #   case insensitive match
360
        #
361
        $file = '';
362
 
363
        #
364
        #   Read directory and cache the results for reuse
365
        #
366
        unless (exists $ExistsDirCache{$curPath})
227 dpurdie 367
        {
6276 dpurdie 368
            if (opendir my $dh, $curPath ) {
369
                @{$ExistsDirCache{$curPath}} = readdir $dh;
370
                closedir $dh;
227 dpurdie 371
            }
372
        }
373
 
6276 dpurdie 374
        #
375
        #   Scan for first matching filename
376
        #
377
        foreach my $item (@{$ExistsDirCache{$curPath}}) {
378
            if (uc($item) eq $ucName) {
379
                $file = $curPath . $item;
380
                last SCANPATHS if ( -f $file );
381
                $file = '';
382
            }
383
        }
384
    } 
385
 
227 dpurdie 386
    #
387
    #   If the user has defined an error message and the file does not
388
    #   exist, then generate an error message
389
    #
390
    Error("$msg","File: $path/$name not found.")
391
        if ($msg && $file eq "");
392
 
6276 dpurdie 393
    Debug2( "Exists:     = $file" );
227 dpurdie 394
    return $file;
395
}
396
 
397
 
398
#-------------------------------------------------------------------------------
399
#   Require( $path, $name, $msg, [@paths] ) ---
400
#
401
#   Description:
402
#       Case insensitive 'require', see Exists() for usage.
403
#
404
#   Returns:
405
#       Full path of resolved filename.
406
#..
407
 
408
sub Require
409
{
410
    my( $file );
411
 
412
    $file = Exists( @_ );
413
    require $file if ($file);
414
    return $file;
415
}
416
 
417
 
418
#   Require2( \@args, $path, $name, $msg, [@paths] ) ---
419
#       Case insensitive 'require' same as Require(), but allows the
420
#       argument list \@args to passed thru to the included image
421
#       via a localised @_.
422
#
423
#   Returns:
424
#       Full path of resolved filename.
425
#..
426
 
427
sub Require2
428
{
429
    my( $args ) = shift;
430
    my( $file, $result );
431
 
432
    $file = Exists( @_ );
433
    if (exists $::INC{$file}) {
434
        Error( "Included $file has already been loaded." );
435
    }
436
    unless (-f $file) {
437
        Error ("Can't locate the include $file");
438
    } else {
439
        local @_;                               # Include argument vector
440
 
441
        push @_, @$args;
442
        $::INC{$file} = $file;
443
        $result = do $file;                     # exec
444
    }
445
    if ($@) {
446
        $::INC{$file} = undef;
447
        Error ($@);
448
    } elsif (!$result) {
449
        delete $::INC{$file};
450
        Error ("Included $file did not return true value.");
451
    }
452
    return $file;
453
}
454
 
455
 
456
sub RequireTool
457
{
458
    my( $script, @arguments ) = @_;
459
    my( $file );
460
 
461
    Debug2( "RequireTool(@_)" );
462
 
463
    $file = Require( "", $script,
464
                "RequireTool", @::BUILDTOOLSPATH, $::GBE_TOOLS );
465
}
466
 
467
 
468
 
469
 
470
#   Trim( string ) ---
471
#       Trim leading/trailing whitespace
472
#..
473
 
474
sub Trim
475
{
476
    my( $str ) = @_;
477
 
478
    if ( $str )
479
    {
480
        $str =~ s/^\s*//g;                          # leading white space
481
        $str =~ s/\s*(\n|$)//;                      # trailing white space
482
    }
483
    return $str;
484
}
485
 
486
 
487
 
488
#   CommifySeries ---
489
#       Format the array into comma seperate list.
490
#..
491
 
492
sub CommifySeries
493
{
494
    my $sepchar = grep(/,/ => @_) ? ";" : ",";
495
 
496
    (@_ == 0) ? '' :
497
    (@_ == 1) ? $_[0] :
498
    (@_ == 2) ? join(" and ", @_)  :
499
                    join("$sepchar ", @_[0 .. ($#_-1)], "and $_[-1]");
500
}
501
 
502
1;  #success
503