Subversion Repositories DevTools

Rev

Rev 271 | Rev 369 | 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
    {
275 dpurdie 352
        my $cfg_file = "$::ScmRoot/$::ScmInterface/$cf_filelist{$dir}";
353
        $self->{IDX}{$dir} = JatsMakeConfigDataReader::New( $cfg_file );
227 dpurdie 354
    }
355
 
356
#    DebugDumpData ("all", \$self );
357
    return bless $self, __PACKAGE__;
358
}
359
 
360
#-------------------------------------------------------------------------------
361
# Function        : AllDirs
362
#
363
# Description     : Return an array of paths required in order to walk the
364
#                   makefiles
365
#
366
#                   The returned order is from the root directory down in the
367
#                   order specified in the build and makefiles.
368
#
369
# Inputs          :
370
#
371
# Returns         : 
372
#
373
sub AllDirs
374
{
375
    my( $self ) = shift;
376
 
377
    #
378
    #   Return cached result
379
    #
380
    return @{$self->{DIRS}}
381
        if ( @{$self->{DIRS}} );
382
 
383
 
384
    #
385
    #   Determine the walking order
386
    #   This is based on the subdir tree
387
    #
388
    sub RecurseDown
389
    {
390
        my ($self, $dir) = @_;
391
        push @{$self->{DIRS}}, $dir;
392
 
393
        foreach my $subdir ( @{$self->{IDX}{$dir}->GetInfoItem('subdirs')} )
394
        {
395
            RecurseDown( $self, CleanDirName( "$dir/$subdir") );
396
        }
397
    }
398
 
399
    #
400
    #   Depth first recursion through the tree
401
    #
402
    RecurseDown ( $self, $::ScmRoot );
403
 
404
    return @{$self->{DIRS}};
405
}
406
 
407
#-------------------------------------------------------------------------------
408
# Function        : GetEntry
409
#
410
# Description     : Return a ref to the makefile data
411
#
412
# Inputs          : 
413
#
414
# Returns         : 
415
#
416
sub GetEntry
417
{
418
    my( $self, $dir ) = @_;
419
    return $self->{IDX}{$dir};
420
}
421
 
422
################################################################################
423
#   Package to contain makefile data reader operations
424
#
425
package JatsMakeConfigDataReader;
426
use JatsError;
275 dpurdie 427
 
227 dpurdie 428
#
429
#   Global data
430
#
431
our %cf_info;                       # Makefile_x.cfg data
432
our %cf_info2;
433
 
434
#-------------------------------------------------------------------------------
435
# Function        : New
436
#
275 dpurdie 437
# Description     : Create an object to contain the Makefile Data
227 dpurdie 438
#
439
# Inputs          : Name of the config file to read
440
#
441
# Returns         : Ref
442
#
443
 
444
sub New
445
{
446
    my ( $cfg_file ) = @_;
447
 
448
    #
449
    #   Create Class Data
450
    #
451
    my ($self) = {
452
            INFO            => {},      # Basic data
453
            FULL            => {},      # Full data
454
            CFG             => {},      # Config files used
455
        };
456
 
457
    Error ("Makefile index entry missing: $cfg_file. Rebuild required")
458
        unless -f $cfg_file;
459
 
460
    %cf_info = ();
461
    %cf_info2 = ();
462
    Verbose ("Reading: $cfg_file");
463
 
464
    delete $INC{ $cfg_file };
465
    require $cfg_file;
466
 
467
    #
468
    #   BAsic sanity test
469
    #
470
    Error ("Makefile info2 not present")
471
        unless ( keys %cf_info2 );
472
 
473
    Error ("Makefile info2 incorrect version. Rebuild required")
474
        unless ( exists $cf_info2{version} && $cf_info2{version} eq 1 );
475
 
476
    $self->{CFG} = $cfg_file;
477
    %{$self->{INFO}} = %cf_info2;
478
    %{$self->{FULL}} = %cf_info;
479
 
480
    return bless $self, __PACKAGE__;
481
}
482
 
483
#-------------------------------------------------------------------------------
484
# Function        : GetPlatforms
485
#
486
# Description     : Return an array of platforms of this makefile
487
#
488
# Inputs          : 
489
#
490
# Returns         : 
491
#
492
sub GetPlatforms
493
{
494
    my( $self ) = @_;
495
    return keys %{$self->{FULL}};
496
}
497
 
498
#-------------------------------------------------------------------------------
499
# Function        : GetData
500
#
501
# Description     : Return a ref to the complete raw data
502
#
503
# Returns         :
504
#
505
sub GetData
506
{
507
    my( $self ) = @_;
508
    return $self->{FULL};
509
}
510
 
511
sub GetInfo
512
{
513
    my( $self ) = @_;
514
    return $self->{INFO};
515
}
516
 
517
#-------------------------------------------------------------------------------
518
# Function        : GetDataItem
519
#
520
# Description     : Return a data item
521
#
522
# Inputs          : self            - Object data
523
#                   platform        - Required platform
524
#                   item            - Item within the platform data
525
#
526
# Returns         : 
527
#
528
 
529
sub GetDataItem
530
{
531
    my( $self, $platform, $item ) = @_;
532
 
533
    return undef unless ( exists $self->{FULL}{$platform} );
534
    return undef unless ( exists $self->{FULL}{$platform}{$item} );
535
 
536
    return $self->{FULL}{$platform}{$item};
537
}
538
 
539
sub GetInfoItem
540
{
541
    my( $self, $item ) = @_;
542
 
543
    return undef unless ( exists $self->{INFO}{$item} );
544
    return $self->{INFO}{$item};
545
}
546
 
275 dpurdie 547
################################################################################
548
################################################################################
549
#   Package to contain makefile data reader operations
550
#   Simple single target reader for use at runtime
551
#
552
#
553
package JatsMakeConfigLoader;
554
use JatsError;
555
use JatsEnv;
556
 
557
#-------------------------------------------------------------------------------
558
# Function        : Load
559
#
560
# Description     : Load Makefile data
561
#                   Uses EnvVars setup by the build system to load the
562
#                   makefile data for the current platform
563
#
564
#                   Used by some utilities that need to access definitions
565
#                   and information available after the makefile has been
566
#                   parsed.
567
#
568
# Inputs          : None
569
#
570
# Returns         : Ref to a class to allow manipulation of the data
571
#
572
sub Load
573
{
574
    #
575
    #   These MUST be in the environment
576
    #
577
    EnvImport ('GBE_MAKE_TYPE');
578
    EnvImport ('GBE_MAKE_TARGET');
579
    EnvImport ('GBE_MAKE_CFG');
580
 
581
    my $data = JatsMakeConfigDataReader::New( $::GBE_MAKE_CFG );
582
 
583
    #
584
    #   Delete data for platforms other than the current one
585
    #   Not essentail, but it will save memory and it will
586
    #   make the data structure easier to debug
587
    #
588
    $data->{FULL} = $data->{FULL}{$::GBE_MAKE_TARGET};
589
 
590
    #
591
    #   Clean up a few items
592
    #   A few items are a hash of items keys on platform name
593
    #   Remove the extra level of indirection to simplify access
594
    #
595
    foreach  ( qw (%ScmBuildPkgRules
596
                   %BUILDINFO
597
                   %BUILDPLATFORM_PARTS
598
                   %ScmBuildProducts )  )
599
    {
600
        $data->{FULL}{$_} = $data->{FULL}{$_}{$::GBE_MAKE_TARGET};
601
    }
602
 
603
    #
604
    #   Add a little bit more data
605
    #
606
    $data->{'PLATFORM'} = $::GBE_MAKE_TARGET;
607
    $data->{'TYPE'} = $::GBE_MAKE_TYPE;
608
 
609
    #
610
    #   Bless myself
611
    #
612
    return bless $data, __PACKAGE__;
613
}
614
 
615
 
616
#-------------------------------------------------------------------------------
617
# Function        : GetData
618
#
619
# Description     : Return a ref to the complete raw data
620
#
621
# Returns         :
622
#
623
sub GetData
624
{
625
    my( $self ) = @_;
626
    return $self->{FULL};
627
}
628
 
629
sub GetInfo
630
{
631
    my( $self ) = @_;
632
    return $self->{INFO};
633
}
634
 
635
#-------------------------------------------------------------------------------
636
# Function        : GetDataItem
637
#
638
# Description     : Return a data item
639
#
640
# Inputs          : self            - Object data
641
#                   item            - Item within the platform data
642
#
643
# Returns         : 
644
#
645
 
646
sub GetDataItem
647
{
648
    my( $self, $item ) = @_;
649
 
650
 
651
    return undef unless ( exists $self->{FULL}{$item} );
652
 
653
    return $self->{FULL}{$item};
654
}
655
 
656
sub GetInfoItem
657
{
658
    my( $self, $item ) = @_;
659
 
660
    return undef unless ( exists $self->{INFO}{$item} );
661
    return $self->{INFO}{$item};
662
}
663
 
664
 
227 dpurdie 665
1;
666
 
667