Subversion Repositories DevTools

Rev

Rev 4836 | 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
4837 dpurdie 42
                GetMakfilefileUid
227 dpurdie 43
            );
44
 
45
#
46
#   Global data
47
#
48
our %cf_filelist;                   # Data from Makefile.cfg
49
our %cf_info;                       # Makefile_x.cfg data
50
our %cf_info2;
51
 
52
#
53
#   Local Data
54
#
4837 dpurdie 55
my $fmtVersion = 1;                 # Data Format. Must match in readers: jmake.pl
227 dpurdie 56
my $cfg_file;                       # Last file read
4837 dpurdie 57
my $cfg_uid;                        # Last file Unique Index
227 dpurdie 58
 
59
#-------------------------------------------------------------------------------
60
# Function        : CheckGlobals
61
#
62
# Description     : Validate assumptions on global variables
63
#
64
# Inputs          : 
65
#
66
# Returns         : 
67
#
68
sub CheckGlobals
69
{
70
    Error ("JatsMakeConfig - ScmRoot not defined") unless ( $::ScmRoot  );
71
    Error ("JatsMakeConfig - ScmInterface not defined") unless ( $::ScmInterface  );
72
    Error ("JatsMakeConfig - Cwd not defined") unless ( $::Cwd  );
73
}
74
 
75
#-------------------------------------------------------------------------------
76
# Function        : ReadConfig
77
#
78
# Description     : Read in a Makefile_x configuration file
79
#
80
# Inputs          : Name of the file to read
81
#
82
# Returns         : 
83
#
84
sub ReadConfig
85
{
86
    ($cfg_file) = @_;
87
 
88
    #
89
    #   Clear before read
90
    #
91
    %cf_info = ();
92
    %cf_info2 = ();
93
 
94
    #
95
    #   Load the existing Parsed Config File
96
    #
97
    if ( -f "$::ScmRoot/$::ScmInterface/$cfg_file" )
98
    {
99
        require "$::ScmRoot/$::ScmInterface/$cfg_file";
100
    }
101
}
102
 
103
#-------------------------------------------------------------------------------
104
# Function        : WriteConfig
105
#
106
# Description     : Writes out the last config file read
107
#                   Maintains the Makefile_x.cfg file
108
#
109
# Inputs          : none
110
#
111
# Returns         : 
112
#
113
sub WriteConfig
114
{
115
    my $fh = ConfigurationFile::New( "$::ScmRoot/$::ScmInterface/$cfg_file" );
116
    $fh->Header( "JatsMakeConfig", "Makefile configuration file" );
117
 
118
#DebugDumpData ("%cf_info2", \%cf_info2);
119
#DebugDumpData ("%cf_info", \%cf_info);
120
 
121
    $fh->Dump([\%cf_info2], [qw(*cf_info2)]);
122
    $fh->Write("\n\n");
123
    $fh->Dump([\%cf_info],  [qw(*cf_info)]);
124
    $fh->Close();
125
}
126
 
127
 
128
#-------------------------------------------------------------------------------
129
# Function        : AllocateParsedConfig
130
#
131
# Description     : Determine the Makefile_X.cfg file to be used for parsed
132
#                   makefile information
133
#
134
#                   This routine will pre-allocate names
135
#                   It may be called to determine the name that will be used
136
#                   The name will be allocated at that point
137
#
138
#                   Maintains Makefile.cfg
139
#                   This is an index file linking paths to Makefile_x.cfg
140
#
141
# Inputs          : None
142
#                   $::Cwd          - Current directory
143
#
144
# Returns         : Name of the config file
145
#
146
sub AllocateParsedConfig
147
{
148
    #
149
    #   Maintain a file of config file names
150
    #   This process will also allocate new configuration file names
151
    #
152
    if ( -f "$::ScmRoot/$::ScmInterface/Makefile.cfg" )
153
    {
154
        require "$::ScmRoot/$::ScmInterface/Makefile.cfg";
155
    }
156
 
157
    my $cfg_file = $cf_filelist{$::Cwd};
158
    unless ( defined( $cfg_file ) )
159
    {
160
        my $num_keys = keys %cf_filelist;
161
        $cfg_file = "Makefile_" . ( $num_keys + 1 ) . ".cfg";
162
        $cf_filelist{$::Cwd} = $cfg_file;
163
 
164
        my $fh = ConfigurationFile::New( "$::ScmRoot/$::ScmInterface/Makefile.cfg" );
165
        $fh->Dump( [\%cf_filelist], [qw(*cf_filelist)] );
166
        $fh->Close();
167
 
168
        #
169
        #   Have allocated a 'new' file
170
        #   Ensure that it doesn't exist. May be left over from another life
171
        #
172
        unlink "$::ScmRoot/$::ScmInterface/$cfg_file";
173
    }
174
 
4837 dpurdie 175
    $cfg_file =~ m~Makefile_(.*)\.cfg~;
176
    $cfg_uid = $1;
177
 
227 dpurdie 178
    return $cfg_file;
179
}
180
 
181
#-------------------------------------------------------------------------------
4837 dpurdie 182
# Function        : GetMakfilefileUid 
183
#
184
# Description     : Return the Makefile's Unqiue ID
185
#
186
# Inputs          : None 
187
#
188
# Returns         : Numeric ID
189
#
190
sub GetMakfilefileUid
191
{
192
    AllocateParsedConfig();
193
    return $cfg_uid;
194
}
195
 
196
#-------------------------------------------------------------------------------
227 dpurdie 197
# Function        : WriteParsedConfig
198
#
199
# Description     : Adds information to the Parsed Config File
200
#                   Does not handle complex structures as a deep copy is
201
#                   not used. In the current implementation this is OK.
202
#
203
# Inputs          :
204
#
205
# Returns         :
206
#
207
sub WriteParsedConfig
208
{
209
 
210
    CheckGlobals();
211
    Error ("ScmPlatform not defined") unless ( $::ScmPlatform );
212
 
213
    #
214
    #   Load the existing Parsed Config File
215
    #
216
    ReadConfig( AllocateParsedConfig() );
217
 
218
    #
219
    #   Remove current information before adding it. This will allow
220
    #   the makefiles to be rebuilt.
221
    #
222
    $cf_info{$::ScmPlatform} = ();
223
 
224
    #
225
    #   Examine the symbol table and capture most of the entries
226
    #
227
    foreach my $symname (keys %main:: )
228
    {
229
        next if ( $symname =~ m/::/  );                 # No Typeglobs
230
        next unless ( $symname =~ m/^[A-Za-z]/  );      # No system type names
231
        next if ( $symname =~ m/^SIG$/  );              # Useless
232
        next if ( $symname =~ m/^ENV$/  );              # Don't keep the user ENV
233
        next if ( $symname =~ m/^INC$/  );              # Don't keep the INC paths
234
        next if ( $symname =~ m/^DEFINES/  );           # Don't keep
235
        next if ( $symname =~ m/^TOOLSETRULES/  );      # Don't keep
271 dpurdie 236
        next if ( $symname =~ m/^RULES/  );             # Don't keep
227 dpurdie 237
 
238
        next if ( $symname =~ m/^ScmCompilerOptions/ );         # Not internal data
239
        next if ( $symname =~ m/^ScmToolsetCompilerOptions/ );  # Not internal data
240
 
241
        local *::sym = $main::{$symname};
242
        $cf_info{$::ScmPlatform}{"\$$symname"} = $::sym  if defined $::sym;
369 dpurdie 243
        $cf_info{$::ScmPlatform}{"\@$symname"} = \@::sym if @::sym;
244
        $cf_info{$::ScmPlatform}{"\%$symname"} = \%::sym if %::sym;
227 dpurdie 245
    }
246
 
247
    #
248
    #   Write out the Parsed Config File with new information
249
    #
250
    WriteConfig();
251
}
252
 
253
 
254
#-------------------------------------------------------------------------------
255
# Function        : WriteCommonInfo
256
#
257
# Description     : Add information to the Makefile_x.cfg file
258
#                   This routine deals with the second section of the file
259
#                   One that is common to all makefiles.
260
#
261
# Inputs          : $SUBDIRS_ref        - Ref to an array of subdirs
262
#                   $PLATFORMS_ref,     - Ref to a hash of platform info
263
#                   $noplatforms,       - 1: No platforms in this dir
264
#                   $rmf                - 1: Root Makefile
265
#
266
# Returns         : 
267
#
268
sub WriteCommonInfo
269
{
270
    my ( $SUBDIRS_ref, $PLATFORMS_ref, $noplatforms, $rmf ) = @_;
271
    CheckGlobals();
272
 
273
    #
274
    #   Load the existing Parsed Config File
275
    #
276
    ReadConfig( AllocateParsedConfig() );
277
 
278
    #
279
    #   Prepare the data
280
    #
281
    %cf_info2 = ();
4837 dpurdie 282
    $cf_info2{version} = $fmtVersion;
227 dpurdie 283
    $cf_info2{subdirs} = $SUBDIRS_ref;
284
    $cf_info2{platforms} = $PLATFORMS_ref;
285
    $cf_info2{noplatforms} = 1 if ( $noplatforms );
286
    $cf_info2{root} = 1 if ( $rmf );
287
 
288
    #
289
    #   Sanity test and cleanse data
290
    #   Remove cf_info entries if the platform is not present
291
    #   Remove the associated .mk file if the platform is not present
292
    #   Note: Assumes that the common part is written after all others
293
    #
294
    foreach my $tgt ( keys %cf_info  )
295
    {
296
        unless ( exists ($cf_info2{platforms}{$tgt}) )
297
        {
298
            Verbose ("WriteCommonInfo:Purge data for $tgt");
299
            delete $cf_info{$tgt};
300
            unlink ($tgt . '.mk');
301
        }
302
    }
303
 
304
 
305
    #
306
    #   Write out the Parsed Config File with new information
307
    #
308
    WriteConfig ();
309
}
310
 
311
################################################################################
312
#   Package to contain makefile reader operations
313
#
314
package JatsMakeConfigReader;
315
use FileUtils;
316
use JatsError;
317
 
318
#
319
#   Global data
320
#
321
our %cf_filelist;                   # Data from Makefile.cfg
322
 
323
#-------------------------------------------------------------------------------
324
# Function        : GetAllMakeInfo
325
#
326
# Description     : This function will read all the Makefile_x.cfg files and
327
#                   create a large data structure that contains all the
328
#                   information
329
#
330
#                   Intended to be used by utiltites that want to process
331
#                   all the information
332
#
333
# Inputs          : Nothing
334
#
335
# Returns         : MakefileInfo Class
336
#
337
sub GetAllMakeInfo
338
{
339
    #
340
    #   Create Class Data
341
    #
342
    my ($self) = {
343
            CFG             => {},      # Config files used
344
            DIRS            => [],      # Array of dirs to walk
345
            IDX             => {},
346
        };
347
 
348
    #
349
    #   Read in the index file
350
    #
351
 
352
    my $fname = "$::ScmRoot/$::ScmInterface/Makefile.cfg";
353
    Error "Cannot locate Make index file: Makefile.cfg\n" unless ( -f $fname );
354
 
355
    delete $INC{ $fname };
356
    require $fname;
357
 
358
    #
359
    #   Validate the index file
360
    #
361
    Error ("Data in Makefile.cfg is not valid - Empty")
362
        unless ( keys(%cf_filelist) > 0 );
363
    Error ("Data in Makefile.cfg is not valid - No Root")
364
        unless ( exists $cf_filelist{$::ScmRoot} );
365
 
366
    #
367
    #   Process all the constituent makefile data and build up a huge data structure
368
    #   Order of reading isn't important. It will be sorted out later
369
    #
370
    foreach my $dir ( keys(%cf_filelist) )
371
    {
275 dpurdie 372
        my $cfg_file = "$::ScmRoot/$::ScmInterface/$cf_filelist{$dir}";
373
        $self->{IDX}{$dir} = JatsMakeConfigDataReader::New( $cfg_file );
227 dpurdie 374
    }
375
 
376
#    DebugDumpData ("all", \$self );
377
    return bless $self, __PACKAGE__;
378
}
379
 
380
#-------------------------------------------------------------------------------
381
# Function        : AllDirs
382
#
383
# Description     : Return an array of paths required in order to walk the
384
#                   makefiles
385
#
386
#                   The returned order is from the root directory down in the
387
#                   order specified in the build and makefiles.
388
#
389
# Inputs          :
390
#
391
# Returns         : 
392
#
393
sub AllDirs
394
{
395
    my( $self ) = shift;
396
 
397
    #
398
    #   Return cached result
399
    #
400
    return @{$self->{DIRS}}
401
        if ( @{$self->{DIRS}} );
402
 
403
 
404
    #
405
    #   Determine the walking order
406
    #   This is based on the subdir tree
407
    #
408
    sub RecurseDown
409
    {
410
        my ($self, $dir) = @_;
411
        push @{$self->{DIRS}}, $dir;
412
 
413
        foreach my $subdir ( @{$self->{IDX}{$dir}->GetInfoItem('subdirs')} )
414
        {
415
            RecurseDown( $self, CleanDirName( "$dir/$subdir") );
416
        }
417
    }
418
 
419
    #
420
    #   Depth first recursion through the tree
421
    #
422
    RecurseDown ( $self, $::ScmRoot );
423
 
424
    return @{$self->{DIRS}};
425
}
426
 
427
#-------------------------------------------------------------------------------
428
# Function        : GetEntry
429
#
430
# Description     : Return a ref to the makefile data
431
#
432
# Inputs          : 
433
#
434
# Returns         : 
435
#
436
sub GetEntry
437
{
438
    my( $self, $dir ) = @_;
439
    return $self->{IDX}{$dir};
440
}
441
 
442
################################################################################
443
#   Package to contain makefile data reader operations
444
#
445
package JatsMakeConfigDataReader;
446
use JatsError;
275 dpurdie 447
 
227 dpurdie 448
#
449
#   Global data
450
#
451
our %cf_info;                       # Makefile_x.cfg data
452
our %cf_info2;
453
 
454
#-------------------------------------------------------------------------------
455
# Function        : New
456
#
275 dpurdie 457
# Description     : Create an object to contain the Makefile Data
227 dpurdie 458
#
459
# Inputs          : Name of the config file to read
460
#
461
# Returns         : Ref
462
#
463
 
464
sub New
465
{
466
    my ( $cfg_file ) = @_;
467
 
468
    #
469
    #   Create Class Data
470
    #
471
    my ($self) = {
472
            INFO            => {},      # Basic data
473
            FULL            => {},      # Full data
474
            CFG             => {},      # Config files used
475
        };
476
 
477
    Error ("Makefile index entry missing: $cfg_file. Rebuild required")
478
        unless -f $cfg_file;
479
 
480
    %cf_info = ();
481
    %cf_info2 = ();
482
    Verbose ("Reading: $cfg_file");
483
 
484
    delete $INC{ $cfg_file };
485
    require $cfg_file;
486
 
487
    #
4837 dpurdie 488
    #   Basic sanity test
227 dpurdie 489
    #
490
    Error ("Makefile info2 not present")
491
        unless ( keys %cf_info2 );
492
 
493
    Error ("Makefile info2 incorrect version. Rebuild required")
4837 dpurdie 494
        unless ( exists $cf_info2{version} && $cf_info2{version} eq $fmtVersion );
227 dpurdie 495
 
496
    $self->{CFG} = $cfg_file;
497
    %{$self->{INFO}} = %cf_info2;
498
    %{$self->{FULL}} = %cf_info;
499
 
500
    return bless $self, __PACKAGE__;
501
}
502
 
503
#-------------------------------------------------------------------------------
504
# Function        : GetPlatforms
505
#
506
# Description     : Return an array of platforms of this makefile
507
#
508
# Inputs          : 
509
#
510
# Returns         : 
511
#
512
sub GetPlatforms
513
{
514
    my( $self ) = @_;
515
    return keys %{$self->{FULL}};
516
}
517
 
518
#-------------------------------------------------------------------------------
519
# Function        : GetData
520
#
521
# Description     : Return a ref to the complete raw data
522
#
523
# Returns         :
524
#
525
sub GetData
526
{
527
    my( $self ) = @_;
528
    return $self->{FULL};
529
}
530
 
531
sub GetInfo
532
{
533
    my( $self ) = @_;
534
    return $self->{INFO};
535
}
536
 
537
#-------------------------------------------------------------------------------
538
# Function        : GetDataItem
539
#
540
# Description     : Return a data item
541
#
542
# Inputs          : self            - Object data
543
#                   platform        - Required platform
544
#                   item            - Item within the platform data
545
#
546
# Returns         : 
547
#
548
 
549
sub GetDataItem
550
{
551
    my( $self, $platform, $item ) = @_;
552
 
553
    return undef unless ( exists $self->{FULL}{$platform} );
554
    return undef unless ( exists $self->{FULL}{$platform}{$item} );
555
 
556
    return $self->{FULL}{$platform}{$item};
557
}
558
 
559
sub GetInfoItem
560
{
561
    my( $self, $item ) = @_;
562
 
563
    return undef unless ( exists $self->{INFO}{$item} );
564
    return $self->{INFO}{$item};
565
}
566
 
275 dpurdie 567
################################################################################
568
################################################################################
569
#   Package to contain makefile data reader operations
570
#   Simple single target reader for use at runtime
571
#
572
#
573
package JatsMakeConfigLoader;
574
use JatsError;
575
use JatsEnv;
576
 
577
#-------------------------------------------------------------------------------
578
# Function        : Load
579
#
580
# Description     : Load Makefile data
581
#                   Uses EnvVars setup by the build system to load the
582
#                   makefile data for the current platform
583
#
584
#                   Used by some utilities that need to access definitions
585
#                   and information available after the makefile has been
586
#                   parsed.
587
#
588
# Inputs          : None
589
#
590
# Returns         : Ref to a class to allow manipulation of the data
591
#
592
sub Load
593
{
594
    #
595
    #   These MUST be in the environment
596
    #
597
    EnvImport ('GBE_MAKE_TYPE');
598
    EnvImport ('GBE_MAKE_TARGET');
599
    EnvImport ('GBE_MAKE_CFG');
600
 
601
    my $data = JatsMakeConfigDataReader::New( $::GBE_MAKE_CFG );
602
 
603
    #
604
    #   Delete data for platforms other than the current one
605
    #   Not essentail, but it will save memory and it will
606
    #   make the data structure easier to debug
607
    #
608
    $data->{FULL} = $data->{FULL}{$::GBE_MAKE_TARGET};
609
 
610
    #
611
    #   Clean up a few items
612
    #   A few items are a hash of items keys on platform name
613
    #   Remove the extra level of indirection to simplify access
614
    #
615
    foreach  ( qw (%ScmBuildPkgRules
616
                   %BUILDINFO
617
                   %BUILDPLATFORM_PARTS
618
                   %ScmBuildProducts )  )
619
    {
620
        $data->{FULL}{$_} = $data->{FULL}{$_}{$::GBE_MAKE_TARGET};
621
    }
622
 
623
    #
624
    #   Add a little bit more data
625
    #
626
    $data->{'PLATFORM'} = $::GBE_MAKE_TARGET;
627
    $data->{'TYPE'} = $::GBE_MAKE_TYPE;
628
 
629
    #
630
    #   Bless myself
631
    #
632
    return bless $data, __PACKAGE__;
633
}
634
 
635
 
636
#-------------------------------------------------------------------------------
637
# Function        : GetData
638
#
639
# Description     : Return a ref to the complete raw data
640
#
641
# Returns         :
642
#
643
sub GetData
644
{
645
    my( $self ) = @_;
646
    return $self->{FULL};
647
}
648
 
649
sub GetInfo
650
{
651
    my( $self ) = @_;
652
    return $self->{INFO};
653
}
654
 
655
#-------------------------------------------------------------------------------
656
# Function        : GetDataItem
657
#
658
# Description     : Return a data item
659
#
660
# Inputs          : self            - Object data
661
#                   item            - Item within the platform data
662
#
663
# Returns         : 
664
#
665
 
666
sub GetDataItem
667
{
668
    my( $self, $item ) = @_;
669
 
670
 
671
    return undef unless ( exists $self->{FULL}{$item} );
672
 
673
    return $self->{FULL}{$item};
674
}
675
 
676
sub GetInfoItem
677
{
678
    my( $self, $item ) = @_;
679
 
680
    return undef unless ( exists $self->{INFO}{$item} );
681
    return $self->{INFO}{$item};
682
}
683
 
684
 
227 dpurdie 685
1;
686
 
687