Subversion Repositories DevTools

Rev

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

Rev Author Line No. Line
227 dpurdie 1
#! perl
2
########################################################################
3
# Copyright ( C ) 2005 ERG Limited, All rights reserved
4
#
5
# Module name   : jats.sh
6
# Module type   : Perl Package
7
# Compiler(s)   : n/a
8
# Environment(s): jats
9
#
10
# Description   : This package contains functions to manipulate
11
#                 the Makefile_x configuration information
12
#
13
#                 This package uses some global variables
14
#
15
#......................................................................#
16
 
255 dpurdie 17
use 5.006_001;
227 dpurdie 18
use strict;
19
use warnings;
20
 
21
################################################################################
22
#   Global variables used by functions in this package
23
#   For historical reasons many of these variabeles are global
24
#
25
 
26
package JatsMakeConfig;
27
use JatsError;
28
use Data::Dumper;
29
use ConfigurationFile;
30
 
31
our (@ISA, @EXPORT, @EXPORT_OK, %EXPORT_TAGS, $VERSION);
32
use Exporter;
33
 
34
$VERSION = 1.00;
35
@ISA = qw(Exporter);
36
 
37
# Symbols to autoexport (:DEFAULT tag)
38
@EXPORT = qw(
39
                AllocateParsedConfig
40
                WriteParsedConfig
41
                WriteCommonInfo
42
            );
43
 
44
#
45
#   Global data
46
#
47
our %cf_filelist;                   # Data from Makefile.cfg
48
our %cf_info;                       # Makefile_x.cfg data
49
our %cf_info2;
50
 
51
#
52
#   Local Data
53
#
54
my $cfg_file;                       # Last file read
55
 
56
 
57
#-------------------------------------------------------------------------------
58
# Function        : CheckGlobals
59
#
60
# Description     : Validate assumptions on global variables
61
#
62
# Inputs          : 
63
#
64
# Returns         : 
65
#
66
sub CheckGlobals
67
{
68
    Error ("JatsMakeConfig - ScmRoot not defined") unless ( $::ScmRoot  );
69
    Error ("JatsMakeConfig - ScmInterface not defined") unless ( $::ScmInterface  );
70
    Error ("JatsMakeConfig - Cwd not defined") unless ( $::Cwd  );
71
}
72
 
73
#-------------------------------------------------------------------------------
74
# Function        : ReadConfig
75
#
76
# Description     : Read in a Makefile_x configuration file
77
#
78
# Inputs          : Name of the file to read
79
#
80
# Returns         : 
81
#
82
sub ReadConfig
83
{
84
    ($cfg_file) = @_;
85
 
86
    #
87
    #   Clear before read
88
    #
89
    %cf_info = ();
90
    %cf_info2 = ();
91
 
92
    #
93
    #   Load the existing Parsed Config File
94
    #
95
    if ( -f "$::ScmRoot/$::ScmInterface/$cfg_file" )
96
    {
97
        require "$::ScmRoot/$::ScmInterface/$cfg_file";
98
    }
99
}
100
 
101
#-------------------------------------------------------------------------------
102
# Function        : WriteConfig
103
#
104
# Description     : Writes out the last config file read
105
#                   Maintains the Makefile_x.cfg file
106
#
107
# Inputs          : none
108
#
109
# Returns         : 
110
#
111
sub WriteConfig
112
{
113
    my $fh = ConfigurationFile::New( "$::ScmRoot/$::ScmInterface/$cfg_file" );
114
    $fh->Header( "JatsMakeConfig", "Makefile configuration file" );
115
 
116
#DebugDumpData ("%cf_info2", \%cf_info2);
117
#DebugDumpData ("%cf_info", \%cf_info);
118
 
119
    $fh->Dump([\%cf_info2], [qw(*cf_info2)]);
120
    $fh->Write("\n\n");
121
    $fh->Dump([\%cf_info],  [qw(*cf_info)]);
122
    $fh->Close();
123
}
124
 
125
 
126
#-------------------------------------------------------------------------------
127
# Function        : AllocateParsedConfig
128
#
129
# Description     : Determine the Makefile_X.cfg file to be used for parsed
130
#                   makefile information
131
#
132
#                   This routine will pre-allocate names
133
#                   It may be called to determine the name that will be used
134
#                   The name will be allocated at that point
135
#
136
#                   Maintains Makefile.cfg
137
#                   This is an index file linking paths to Makefile_x.cfg
138
#
139
# Inputs          : None
140
#                   $::Cwd          - Current directory
141
#
142
# Returns         : Name of the config file
143
#
144
sub AllocateParsedConfig
145
{
146
    #
147
    #   Maintain a file of config file names
148
    #   This process will also allocate new configuration file names
149
    #
150
    if ( -f "$::ScmRoot/$::ScmInterface/Makefile.cfg" )
151
    {
152
        require "$::ScmRoot/$::ScmInterface/Makefile.cfg";
153
    }
154
 
155
    my $cfg_file = $cf_filelist{$::Cwd};
156
    unless ( defined( $cfg_file ) )
157
    {
158
        my $num_keys = keys %cf_filelist;
159
        $cfg_file = "Makefile_" . ( $num_keys + 1 ) . ".cfg";
160
        $cf_filelist{$::Cwd} = $cfg_file;
161
 
162
        my $fh = ConfigurationFile::New( "$::ScmRoot/$::ScmInterface/Makefile.cfg" );
163
        $fh->Dump( [\%cf_filelist], [qw(*cf_filelist)] );
164
        $fh->Close();
165
 
166
        #
167
        #   Have allocated a 'new' file
168
        #   Ensure that it doesn't exist. May be left over from another life
169
        #
170
        unlink "$::ScmRoot/$::ScmInterface/$cfg_file";
171
    }
172
 
173
    return $cfg_file;
174
}
175
 
176
#-------------------------------------------------------------------------------
177
# Function        : WriteParsedConfig
178
#
179
# Description     : Adds information to the Parsed Config File
180
#                   Does not handle complex structures as a deep copy is
181
#                   not used. In the current implementation this is OK.
182
#
183
# Inputs          :
184
#
185
# Returns         :
186
#
187
sub WriteParsedConfig
188
{
189
 
190
    CheckGlobals();
191
    Error ("ScmPlatform not defined") unless ( $::ScmPlatform );
192
 
193
    #
194
    #   Load the existing Parsed Config File
195
    #
196
    ReadConfig( AllocateParsedConfig() );
197
 
198
    #
199
    #   Remove current information before adding it. This will allow
200
    #   the makefiles to be rebuilt.
201
    #
202
    $cf_info{$::ScmPlatform} = ();
203
 
204
    #
205
    #   Examine the symbol table and capture most of the entries
206
    #
207
    foreach my $symname (keys %main:: )
208
    {
209
        next if ( $symname =~ m/::/  );                 # No Typeglobs
210
        next unless ( $symname =~ m/^[A-Za-z]/  );      # No system type names
211
        next if ( $symname =~ m/^SIG$/  );              # Useless
212
        next if ( $symname =~ m/^ENV$/  );              # Don't keep the user ENV
213
        next if ( $symname =~ m/^INC$/  );              # Don't keep the INC paths
214
        next if ( $symname =~ m/^DEFINES/  );           # Don't keep
215
        next if ( $symname =~ m/^TOOLSETRULES/  );      # Don't keep
271 dpurdie 216
        next if ( $symname =~ m/^RULES/  );             # Don't keep
227 dpurdie 217
 
218
        next if ( $symname =~ m/^ScmCompilerOptions/ );         # Not internal data
219
        next if ( $symname =~ m/^ScmToolsetCompilerOptions/ );  # Not internal data
220
 
221
        local *::sym = $main::{$symname};
222
        $cf_info{$::ScmPlatform}{"\$$symname"} = $::sym  if defined $::sym;
223
        $cf_info{$::ScmPlatform}{"\@$symname"} = \@::sym if defined @::sym;
224
        $cf_info{$::ScmPlatform}{"\%$symname"} = \%::sym if defined %::sym;
225
    }
226
 
227
    #
228
    #   Write out the Parsed Config File with new information
229
    #
230
    WriteConfig();
231
}
232
 
233
 
234
#-------------------------------------------------------------------------------
235
# Function        : WriteCommonInfo
236
#
237
# Description     : Add information to the Makefile_x.cfg file
238
#                   This routine deals with the second section of the file
239
#                   One that is common to all makefiles.
240
#
241
# Inputs          : $SUBDIRS_ref        - Ref to an array of subdirs
242
#                   $PLATFORMS_ref,     - Ref to a hash of platform info
243
#                   $noplatforms,       - 1: No platforms in this dir
244
#                   $rmf                - 1: Root Makefile
245
#
246
# Returns         : 
247
#
248
sub WriteCommonInfo
249
{
250
    my ( $SUBDIRS_ref, $PLATFORMS_ref, $noplatforms, $rmf ) = @_;
251
    CheckGlobals();
252
 
253
    #
254
    #   Load the existing Parsed Config File
255
    #
256
    ReadConfig( AllocateParsedConfig() );
257
 
258
    #
259
    #   Prepare the data
260
    #
261
    %cf_info2 = ();
262
    $cf_info2{version} = 1;
263
    $cf_info2{subdirs} = $SUBDIRS_ref;
264
    $cf_info2{platforms} = $PLATFORMS_ref;
265
    $cf_info2{noplatforms} = 1 if ( $noplatforms );
266
    $cf_info2{root} = 1 if ( $rmf );
267
 
268
    #
269
    #   Sanity test and cleanse data
270
    #   Remove cf_info entries if the platform is not present
271
    #   Remove the associated .mk file if the platform is not present
272
    #   Note: Assumes that the common part is written after all others
273
    #
274
    foreach my $tgt ( keys %cf_info  )
275
    {
276
        unless ( exists ($cf_info2{platforms}{$tgt}) )
277
        {
278
            Verbose ("WriteCommonInfo:Purge data for $tgt");
279
            delete $cf_info{$tgt};
280
            unlink ($tgt . '.mk');
281
        }
282
    }
283
 
284
 
285
    #
286
    #   Write out the Parsed Config File with new information
287
    #
288
    WriteConfig ();
289
}
290
 
291
################################################################################
292
#   Package to contain makefile reader operations
293
#
294
package JatsMakeConfigReader;
295
use FileUtils;
296
use JatsError;
297
 
298
#
299
#   Global data
300
#
301
our %cf_filelist;                   # Data from Makefile.cfg
302
 
303
#-------------------------------------------------------------------------------
304
# Function        : GetAllMakeInfo
305
#
306
# Description     : This function will read all the Makefile_x.cfg files and
307
#                   create a large data structure that contains all the
308
#                   information
309
#
310
#                   Intended to be used by utiltites that want to process
311
#                   all the information
312
#
313
# Inputs          : Nothing
314
#
315
# Returns         : MakefileInfo Class
316
#
317
sub GetAllMakeInfo
318
{
319
    #
320
    #   Create Class Data
321
    #
322
    my ($self) = {
323
            CFG             => {},      # Config files used
324
            DIRS            => [],      # Array of dirs to walk
325
            IDX             => {},
326
        };
327
 
328
    #
329
    #   Read in the index file
330
    #
331
 
332
    my $fname = "$::ScmRoot/$::ScmInterface/Makefile.cfg";
333
    Error "Cannot locate Make index file: Makefile.cfg\n" unless ( -f $fname );
334
 
335
    delete $INC{ $fname };
336
    require $fname;
337
 
338
    #
339
    #   Validate the index file
340
    #
341
    Error ("Data in Makefile.cfg is not valid - Empty")
342
        unless ( keys(%cf_filelist) > 0 );
343
    Error ("Data in Makefile.cfg is not valid - No Root")
344
        unless ( exists $cf_filelist{$::ScmRoot} );
345
 
346
    #
347
    #   Process all the constituent makefile data and build up a huge data structure
348
    #   Order of reading isn't important. It will be sorted out later
349
    #
350
    foreach my $dir ( keys(%cf_filelist) )
351
    {
352
        $self->{IDX}{$dir} = JatsMakeConfigDataReader::New( $cf_filelist{$dir} );
353
    }
354
 
355
#    DebugDumpData ("all", \$self );
356
    return bless $self, __PACKAGE__;
357
}
358
 
359
#-------------------------------------------------------------------------------
360
# Function        : AllDirs
361
#
362
# Description     : Return an array of paths required in order to walk the
363
#                   makefiles
364
#
365
#                   The returned order is from the root directory down in the
366
#                   order specified in the build and makefiles.
367
#
368
# Inputs          :
369
#
370
# Returns         : 
371
#
372
sub AllDirs
373
{
374
    my( $self ) = shift;
375
 
376
    #
377
    #   Return cached result
378
    #
379
    return @{$self->{DIRS}}
380
        if ( @{$self->{DIRS}} );
381
 
382
 
383
    #
384
    #   Determine the walking order
385
    #   This is based on the subdir tree
386
    #
387
    sub RecurseDown
388
    {
389
        my ($self, $dir) = @_;
390
        push @{$self->{DIRS}}, $dir;
391
 
392
        foreach my $subdir ( @{$self->{IDX}{$dir}->GetInfoItem('subdirs')} )
393
        {
394
            RecurseDown( $self, CleanDirName( "$dir/$subdir") );
395
        }
396
    }
397
 
398
    #
399
    #   Depth first recursion through the tree
400
    #
401
    RecurseDown ( $self, $::ScmRoot );
402
 
403
    return @{$self->{DIRS}};
404
}
405
 
406
#-------------------------------------------------------------------------------
407
# Function        : GetEntry
408
#
409
# Description     : Return a ref to the makefile data
410
#
411
# Inputs          : 
412
#
413
# Returns         : 
414
#
415
sub GetEntry
416
{
417
    my( $self, $dir ) = @_;
418
    return $self->{IDX}{$dir};
419
}
420
 
421
################################################################################
422
#   Package to contain makefile data reader operations
423
#
424
package JatsMakeConfigDataReader;
425
use JatsError;
426
#
427
#   Global data
428
#
429
our %cf_info;                       # Makefile_x.cfg data
430
our %cf_info2;
431
 
432
#-------------------------------------------------------------------------------
433
# Function        : New
434
#
435
# Description     : Create an object to conatin the Makefile Data
436
#
437
# Inputs          : Name of the config file to read
438
#
439
# Returns         : Ref
440
#
441
 
442
sub New
443
{
444
    my ( $cfg_file ) = @_;
445
 
446
    #
447
    #   Create Class Data
448
    #
449
    my ($self) = {
450
            INFO            => {},      # Basic data
451
            FULL            => {},      # Full data
452
            CFG             => {},      # Config files used
453
        };
454
 
455
    $cfg_file = "$::ScmRoot/$::ScmInterface/$cfg_file";
456
    Error ("Makefile index entry missing: $cfg_file. Rebuild required")
457
        unless -f $cfg_file;
458
 
459
    %cf_info = ();
460
    %cf_info2 = ();
461
    Verbose ("Reading: $cfg_file");
462
 
463
    delete $INC{ $cfg_file };
464
    require $cfg_file;
465
 
466
    #
467
    #   BAsic sanity test
468
    #
469
    Error ("Makefile info2 not present")
470
        unless ( keys %cf_info2 );
471
 
472
    Error ("Makefile info2 incorrect version. Rebuild required")
473
        unless ( exists $cf_info2{version} && $cf_info2{version} eq 1 );
474
 
475
    $self->{CFG} = $cfg_file;
476
    %{$self->{INFO}} = %cf_info2;
477
    %{$self->{FULL}} = %cf_info;
478
 
479
    return bless $self, __PACKAGE__;
480
}
481
 
482
#-------------------------------------------------------------------------------
483
# Function        : GetPlatforms
484
#
485
# Description     : Return an array of platforms of this makefile
486
#
487
# Inputs          : 
488
#
489
# Returns         : 
490
#
491
sub GetPlatforms
492
{
493
    my( $self ) = @_;
494
    return keys %{$self->{FULL}};
495
}
496
 
497
#-------------------------------------------------------------------------------
498
# Function        : GetData
499
#
500
# Description     : Return a ref to the complete raw data
501
#
502
# Returns         :
503
#
504
sub GetData
505
{
506
    my( $self ) = @_;
507
    return $self->{FULL};
508
}
509
 
510
sub GetInfo
511
{
512
    my( $self ) = @_;
513
    return $self->{INFO};
514
}
515
 
516
#-------------------------------------------------------------------------------
517
# Function        : GetDataItem
518
#
519
# Description     : Return a data item
520
#
521
# Inputs          : self            - Object data
522
#                   platform        - Required platform
523
#                   item            - Item within the platform data
524
#
525
# Returns         : 
526
#
527
 
528
sub GetDataItem
529
{
530
    my( $self, $platform, $item ) = @_;
531
 
532
    return undef unless ( exists $self->{FULL}{$platform} );
533
    return undef unless ( exists $self->{FULL}{$platform}{$item} );
534
 
535
    return $self->{FULL}{$platform}{$item};
536
}
537
 
538
sub GetInfoItem
539
{
540
    my( $self, $item ) = @_;
541
 
542
    return undef unless ( exists $self->{INFO}{$item} );
543
    return $self->{INFO}{$item};
544
}
545
 
546
1;
547
 
548