Subversion Repositories DevTools

Rev

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