Subversion Repositories DevTools

Rev

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

Rev Author Line No. Line
271 dpurdie 1
########################################################################
6177 dpurdie 2
# COPYRIGHT - VIX IP PTY LTD ("VIX"). ALL RIGHTS RESERVED.
271 dpurdie 3
#
4
# Module name   : MakeIf.pm
5
# Module type   : JATS Internal
6
# Compiler(s)   : Perl
7
# Environment(s): JATS
8
#
9
# Description   : This modules builds an object that provides
10
#                 an interface to the underlying toolset
11
#
12
#                 It is overly complicated
13
#
14
#                       *** DO NOT DETAB ***
15
#
16
#......................................................................#
17
 
18
use strict;
19
use warnings;
20
 
21
#
22
#   System Globals
23
#   Declared to avoid compile errors
24
#
25
our $ScmVersion;
26
our $ScmTargetHost;
27
our @TESTPROJECT_TO_ARUN;
28
our @TESTPROJECT_TO_URUN;
29
our $ToolsetPROJECT_type;
30
 
31
###############################################################################
32
#   MakeInterface ---
33
#       Interface framework
34
#
35
#   Push                Push a package into the interface stack.
36
#   Factory             Build a interface.
37
#   Load                Loads the specified interface
38
#...
39
 
40
package MakeIf;
41
 
42
use strict;
43
use warnings;
44
 
45
our (@IfStack)              = ();               # interface stack
46
 
47
#-------------------------------------------------------------------------------
48
# Function        : Makeif::Push
49
#
50
# Description     : Push a toolset interface onto a list of such items
51
#                   Will be used later to construct the toolset interface
52
#
53
# Inputs          : *                       - List of packages to push
54
#
55
# Returns         : Nothing
56
#
57
sub Push
58
{
59
    ::Debug( "MakeIf::Push( @_ )" );
60
    push (@IfStack, @_);                        # push onto stack
61
}
62
 
63
#-------------------------------------------------------------------------------
64
# Function        : MakeIf::Factory
65
#
66
# Description     : Build a interface.
67
#                   Creates a Toolset Interface from all the toolsets
68
#                   that have been pushed on to the list of toolsets
69
#
70
#                   The user is provided the reference to the composite
71
#                   interface created such that it inherits properties from
72
#                   all the other toolsets
73
#
74
# Inputs          : None
75
#
76
# Returns         : Refernece to the constructed interface
77
#
78
sub Factory
79
{
4761 dpurdie 80
    # Add myself to the list of dependent packages
81
    #   Only really needed in development
82
    push (@::ScmDepends, __FILE__);
83
 
271 dpurdie 84
    sub Unroll
85
    {
86
        my ($stack) = @_;                       # current
87
        my ($package, $base, $self);
88
 
89
        #
90
        #   First package on the stack MUST be the BASE_Toolset
91
        #   This has a 'Spawn' method that must be invoked
92
        #
93
        $package = shift(@$stack);              # base class
94
        ::Error( "Interface -- base-class $package cannot Spawn." )
95
            unless( $package->can( "Spawn" ));
96
 
97
        $self = $package->Spawn();
98
 
99
        #
100
        #   Process the remainder of the toolsets on the stack
101
        #       1) Cause package to inherit previous package stuff
102
        #       2) Invoke any local conststructor
103
        #
104
        while (scalar(@$stack))
105
        {                                       # child
106
            my ($has_constructor);
107
 
108
            $base = $package;
109
            $package = shift(@$stack);
110
 
111
            no strict 'refs';
112
 
113
            ::Warning( "Interface --- base package $base is empty." )
114
                unless (%{"$base\::"});
115
 
116
            $has_constructor = $package->can( "Constructor" );
117
 
118
            push @{"$package\::ISA"}, $base;    # inherit class(es)
119
            bless ($self, $package);            # consecrate
120
 
121
            $self->Constructor()                # 'local' constructor
122
                if ($has_constructor);
123
        }
124
 
125
        return ($self);
126
    }
127
 
128
    my (@stack) = @IfStack;                     # clone stack
129
    my ($self);
130
 
131
    ::Error( "Interface -- object stack empty." )
132
        if ( ! scalar (@stack) );
133
    $self = Unroll( \@stack) ||
134
        ::Error( "Interface --- cannot build interface object." );
135
#::DebugDumpData("Factory Stack", \@IfStack );
136
#::DebugDumpData("Factory", $self );
137
    return $self;
138
}
139
 
140
#-------------------------------------------------------------------------------
141
# Function        : MakeIf::Load
142
#
143
# Description     : Loads the specified interface
144
#                   This function will create a new 'class' based on the
145
#                   data within the DPACKAGE and DPACKAGE.CFG files
146
#                   within a consumed package
147
#
148
#                   The DPACKAGE file should use the 'Interface()' directive
149
#                   to add the created package onto the Interface list
150
#
299 dpurdie 151
# Inputs          : $dir            - Config directory within the package
152
#                   $file           - DPACKAGE file within the dir
153
#                   $dpackage       - Name of the Package containg file to load
271 dpurdie 154
#                   $root           - Base directory of the package
155
#                   $project        - Package project suffix (optional)
156
#
157
# Returns         : Nothing
158
#
159
sub Load
160
{
299 dpurdie 161
    my ($dir, $file, $dpackage, $root, $project) = @_;
271 dpurdie 162
 
163
    #
164
    #   Create the basic template class
165
    #
166
    my $if = Template ($dpackage, $project);
167
 
168
    #
169
    #   Insert essential information into the Interface
170
    #   Invoke functions within the Interface Class to do this
171
    #
172
    $if->setRoot($root);
299 dpurdie 173
    $if->ReadFiles( "$dir/DPACKAGE.CFG", "$dir/$file" );
271 dpurdie 174
}
175
 
176
#-------------------------------------------------------------------------------
177
# Function        : Template
178
#
179
# Description     : Create a new skeleton template for a toolset interface
180
#                   package. The details of the package will be beefed out
181
#                   later
182
#
183
# Inputs          : $dpackage       - Name of the Package containg file to load
184
#                   $project        - Package project suffix (optional)
185
#
186
# Returns         : Nothing
187
#
188
sub Template
189
{
190
    my ($dpackage, $project) = @_;
191
    my ($package, $template );
192
 
193
    #
194
    #   The code will not work if dpackage has a "-" in it
195
    #   Replace nasty characters with nice ones
196
    #
197
    $project = '' unless ( $project );
198
    $dpackage =~ s~-~_~g;
199
    $package = $dpackage . "_" . $project . "_DPACKAGE";
200
 
201
    $template = (<< '__END_OF_DPACKAGE_TEMPLATE__');
202
########################################################################
203
#
204
#   DPACKAGE Template -- version (1.x)
205
#
206
#       Version         State interface version requirements.
207
#       Using           Using statement.
208
#       Needs           Pre-req
209
#       Interface       Push onto the interface stack.
210
#       Self            Our reference.
211
#       Package         Package name.
212
#       Name            Name of perl package.
213
#       Root            Root directory of our installation.
214
#       Debug           General purpose debug output.
215
#
216
#   Initialisation
217
#       setRoot         Configure package Root
218
#       ReadFiles       Read DPACKAGE files into the class
219
#..
220
package __PACKAGE__;
221
 
222
use strict;
223
use warnings;
224
 
225
our $VERSION='1.00';                            # Template version
226
our $SelfReference;
227
 
228
DPACKAGE_Initialise();
229
 
230
sub DPACKAGE_Initialise {
231
    my $self = {
232
            PACKAGE     => "__DPACKAGE__",
233
            NAME        => "__PACKAGE__",
234
            ROOT        => "__ROOT__"
235
        };
236
    $SelfReference = bless $self, "__PACKAGE__";
237
}
238
 
239
sub setRoot             { $_[0]->{ROOT} = $_[1]; }
240
sub Self                { return $SelfReference; }
241
sub Package             { $SelfReference->{PACKAGE}; }
242
sub Name                { $SelfReference->{NAME}; }
243
sub Root                { $SelfReference->{ROOT}; }
244
sub Interface           { MakeIf::Push( "__PACKAGE__" ); }
245
sub Debug               { ::Debug @_; }
246
sub Debug2              { ::Debug2 @_; }
247
sub Debug3              { ::Debug3 @_; }
248
sub Error               { ::Error @_; }
249
 
250
 
251
sub Version
252
{
253
    my ($major, $minor) = @_;
254
    Error( "DPACKAGE $SelfReference->{PACKAGE} requires Version($major,$minor)" )
255
        if ($major != 1 || $minor != 0);
256
}
257
 
258
 
259
sub Using
260
{
261
    my ($using) = @_;
262
    $SelfReference->{USING} = $using;
263
}
264
 
265
 
266
sub Needs
267
{
268
    my ($name, $version) = @_;
269
 
270
    #   TODO - statement of DPACKAGE prereqs.
271
    #
272
    #   name                Package name
273
    #
274
    #   Version [optional]
275
    #       =xx.xx.xx       Absolute
276
    #       >=xx.xx.xx      Greater or equal.  Where xx respresents
277
    #                       either, * or missing.
278
    #...
279
}
280
 
281
 
282
sub IncDir
283
{
284
    #TODO
285
}
286
 
287
sub LibDir
288
{
289
    #TODO
290
}
291
 
292
sub Libraries
293
{
294
    my ($caller, $file, $line) = caller();
295
 
296
    Error( "$SelfReference->{PACKAGE} ($line) requires Using()" )
297
        if ( ! defined( $SelfReference->{USING} ) );
298
 
299
    MakeIf::Libaries( $SelfReference->{USING}, @_ );
300
}
301
 
302
#
303
#   Designed to be called externally though the class interface
304
#   As the first argument is the class ref
305
#
306
sub ReadFiles
307
{
308
    my $self = shift;
309
    my $code;
310
    foreach my $file ( @_ )
311
    {
312
        if ( -e $file )
313
        {
314
            open(CFGFILE, $file) || Error( "Cannot open '$file'" );
315
            $code .= "# line 1 " . $file . "\n";    # name the image
316
            while (<CFGFILE>) {
317
                $code .= $_;                        # slurp text
318
            }
319
            close (CFGFILE);
369 dpurdie 320
 
321
            #
322
            #   Add the file to the makefile dependency list
323
            #   Really only needed if being sourced from within a sandbox
324
            #
325
            push (@::ScmDepends, $file);
271 dpurdie 326
        }
327
    }
328
 
329
    #
330
    #   Evaluate the code
331
    #
332
    eval "$code";
333
    Error("DPACKAGE Syntax. Package: $SelfReference->{ROOT}", "Err: $@" ) if ($@);
334
}
335
 
336
sub EvaluateText
337
{
338
    my $this = shift;
339
    eval "@_";
340
    Error("DPACKAGE Syntax. Package: $SelfReference->{ROOT}", "Err: $@" ) if ($@);
341
}
342
 
343
###########################################################################
344
#   -END-
345
#
346
__END_OF_DPACKAGE_TEMPLATE__
347
 
348
    $template =~ s/__PACKAGE__/$package/g;      # preprocess template
349
    $template =~ s/__DPACKAGE__/$dpackage/g;
350
 
351
    #
352
    #   Have the template for the class in a text string
353
    #   Create it at run-time
354
    #
355
    my $if = eval "# line 1 \"DPACKAGE_TEMPLATE\"\n".   # name the image
356
         "$template";                                   # .. template code
357
    ::Error("JATS INTERNAL. MakeIf Template", "Err: $@" )
358
        if ($@);
359
    return $if;
360
}
361
 
362
###############################################################################
363
#   DPACKAGE Interface
364
#
369 dpurdie 365
#       PackageLoad     Load the DPACKAGES for specified platform(s).
271 dpurdie 366
#
367
#       PackageDirs     Retrieve the search path for package configuration.
368
#
369
#       LibUsing        Processing Using(XXX) library recipes
370
#
371
#       LibProcess      Apply library ordering rules.
372
#
373
#       ExportDepend    Export a local package dependency list.
374
#..
375
 
376
our %IfPkgLibaries        = ();
377
our %IfPkgOrdering        =
378
        (
379
            'User'      => '0',                 # User (default)
380
 
381
            'App'       => '3',                 # Application common
382
            'App2'      => '3a',
383
            'App3'      => '3b',
384
            'App4'      => '3c',
385
 
386
            'If'        => '5',                 # Interface
387
            'If2'       => '5a',
388
            'If3'       => '5b',
389
            'If4'       => '5c',
390
 
391
            'Kern'      => '7',                 # Kernel (ie MOS, LMOS)
392
            'Kern2'     => '7a',
393
            'Kern3'     => '7b',
394
            'Kern4'     => '7c',
395
 
396
            'Sys'       => '9',                 # System (ie WIN32, Linux)
397
            'Sys2'      => '9a',
398
            'Sys3'      => '9b',
399
            'Sys4'      => '9c'
400
        );
401
 
402
#
403
#   Provide reverse lookup of the %IfPkgOrdering for error reporting purposes
404
#   It may be slow, but its not used (Often).
405
#
406
sub ClassNumToText
407
{
408
    my (@classes) = @_;
409
    my @result;
410
 
411
    foreach my $class ( @classes )
412
    {
413
        my $result = "Unknown Class($class)";
414
        foreach ( keys %IfPkgOrdering )
415
        {
416
            if ( $IfPkgOrdering{$_} eq $class )
417
            {
418
                $result = $_;
419
                last;
420
            }
421
        }
422
        push @result, $result;
423
    }
424
    return @result;
425
}
426
 
427
#-------------------------------------------------------------------------------
428
# Function        : PackageLoad
429
#
430
# Description     : Scan all external packages and locate DPACKAGE files
431
#                   This will (must) be in the JATS config directory (gbe)
432
#
433
#                   Once found they will be loaded into the system
434
#                   This will effectivly extend the base toolset
435
#
436
# Inputs          : $platform               - target platform
437
#                                             Only used to locate packages
438
#                                             Not 'really' used
439
#
440
# Returns         : Nothing
441
#
442
sub PackageLoad
443
{
444
    my ($platform) = @_;
445
    ::Debug ("PackageLoad", @_);
446
 
369 dpurdie 447
    return if ( !(%::ScmBuildPkgRules) );# configuration available
271 dpurdie 448
 
449
    my $pPlatform = $::ScmBuildPkgRules{$platform};
450
    foreach my $package ( @{$pPlatform} )
451
    {
452
        if ( defined( $package->{'CFGDIR'} ) )
453
        {
454
            my ($dir) = $package->{'ROOT'}.$package->{'CFGDIR'};
455
 
299 dpurdie 456
            #
457
            #   Look for both forms:
458
            #       DPACKAGE.GBE_MACHTYPE   ( New format )
459
            #       DPACKAGE                ( Manually created and Old format )
460
            #   Use only the first
461
            #
462
            foreach my $ext ( '.' . $::GBE_MACHTYPE, '' )
463
            {
464
                my $dpackage = "DPACKAGE" . $ext;
465
                ::Debug( "Examine $dir/$dpackage" );
466
                if ( -e "$dir/$dpackage" )
467
                {                                   # .. load interface
468
                    ::Debug( "Loading $dir/$dpackage ($package->{'NAME'}) ..." );
469
                    MakeIf::Load( $dir, $dpackage, $package->{'NAME'}, $package->{'ROOT'}, $package->{'DPROJ'} );
470
                    last;
471
                }
271 dpurdie 472
            }
473
        }
474
    }
475
}
476
 
477
#-------------------------------------------------------------------------------
478
# Function        : PackageDirs
479
#
480
# Description     : Extend an array of 'search' directories to include
481
#                   'gbe' extension directories located with external toolsets
482
#
483
#                   Scan the package information held in ScmBuildPkgRules
484
#                   and locate 'gbe' directories.
485
#
486
# Inputs          : $dirs       - Ref to an array to extend
487
#                   @platforms  - A list of platforms to scan
488
#
489
# Returns         : Nothing
490
#
491
sub PackageDirs
492
{
493
    my ($dirs, @platforms) = @_;
494
 
369 dpurdie 495
    if ( (%::ScmBuildPkgRules) )
271 dpurdie 496
    {
497
        for my $platform (@platforms)
498
        {
499
            my $pPlatform = $::ScmBuildPkgRules{$platform};
500
 
501
            foreach my $package ( @$pPlatform )
502
            {
503
                push @$dirs, $package->{'ROOT'}.$package->{'CFGDIR'}
504
                    if ( defined( $package->{'CFGDIR'} ) );
505
            }
506
        }
507
    }
508
}
509
 
510
#-------------------------------------------------------------------------------
511
# Function        : MakeIf::Libaries
512
#
513
# Description     : Maintain a data structure for the --Using() expansion
514
#
515
# Inputs          : $using              - Name of the Macro
516
#                   $platform           - Active platform predicate
517
#                   @libs               - List of Libraries
518
#
519
# Returns         : Nothing
520
#
521
sub Libaries
522
{
523
    my ($using, $platforms, @libs) = @_;
524
    my $recipe;
525
 
526
    ::Debug2( "Makeif::Libraries($using, $platforms, @libs)" );
527
    return if ( ! ::ActivePlatform($platforms) );
528
 
529
    push @{$IfPkgLibaries{$using}{LIBS}}, @libs;
530
}
531
 
532
 
533
#private
534
sub LibUsing
535
{
536
    my ($caller, $args, $libs) = @_;
537
    my ($using, @args) = split( ',', $args );
538
 
539
    ::Debug2( "Makeif::LibUsing($caller->$args)" );
540
 
541
    # Global arguments (if any)
542
    #
543
    #   ie. --Using(XXX)[,--NoWarn][,--ifdef USING_XXX]
544
    #
545
    my ($x_nowarn, $x_conds) = (0, 0);
546
 
547
    foreach (@args) {
548
        if ( /^--NoWarn$/ ) {                   # .. disable warnings
549
            $x_nowarn = 1;
550
 
551
        } elsif ( /^--if(.*)$/ ) {              # .. conditional(s)
552
            $x_conds .= "," if ($x_conds);
553
            $x_conds .= $_;
554
 
555
        } else {
556
            ::Warning( "$caller->Using($using), unknown option '$_'" );
557
        }
558
    }
559
 
560
 
561
    # Sanity test
562
    #   Recipe Entry Must Exist
563
    #   Detect recursive invocation
564
    #
565
    my $recipe = $IfPkgLibaries{$using};
566
    unless ( $recipe )
567
    {
568
        ::Warning( "$caller->Using($using), module not found" )
569
            unless ( $x_nowarn );
570
        return;
571
    }
572
 
573
    if ( $recipe->{COOKED} ) {
574
        ::Warning( "$caller->Using($using) causes loop, ignored" )
575
            unless ($recipe->{COOKED_ERR} );
576
        $recipe->{COOKED_ERR}++;
577
        return;
578
    }
579
 
580
    # Parse Using arguments
581
    my ($arg, $deforder, $defallowdup, $defnowarn, @defconds);
582
    $deforder = "User";                 # default "class"
583
    $defallowdup = 0;
584
    $defnowarn = 0;
585
 
586
    foreach (@{$recipe->{LIBS}})
587
    {
588
        # Locally processed switches (global/default settings)
589
        #
590
        if ( /^--DefOrder=(.*)$/ ) {
591
            $deforder = $1;             # Sort using name
592
            next;
593
        }
594
        if ( /^--DefAllowDup$/ ) {
595
            $defallowdup = 1;
596
            next;
597
        }
598
        if ( /^--DefNoWarn$/ ) {
599
            $defnowarn = 1;
600
            next;
601
        }
602
 
603
        if ( /^--DefCond\((.*)\)$/ ) {
604
            my (@conds) = split( ',', $1 );
605
 
606
            @defconds = ();
607
            foreach (@conds) {
608
                Error( "Invalid --DeCond argument '$_' " )
609
                    if ( ! /^--if/ );
610
                push @defconds, $_;
611
            }
612
            next;
613
        }
614
 
615
        # Handle indirections
616
        #
617
        if ( /^--Using\((.*)\)(.*)$/ )
618
        {                               # recurse
619
            my ($x_using);
620
 
621
            $x_using  = "$1";
622
            $x_using .= ",$x_conds"     if ( $x_conds );
623
            $x_using .= "$2";
624
 
625
            $recipe->{COOKED}++;
626
            LibUsing( $using, $x_using, $libs );
627
            $recipe->{COOKED}--;
628
            next;
629
        }
630
 
631
        # Libraries and arguments
632
        #
633
        if ( /^-[lL].*/ )
634
        {                               # Library
635
            my ($order, $allowdup, $nowarn, @conds) =
636
                ($deforder, $defallowdup, $defnowarn, @defconds);
637
            my (@args) = split( ',', $_ );
638
 
639
            foreach (@args) {
640
                if ( /^-([lL])(.*)/ ) {
641
                    $arg = $_;
642
                } elsif ( /^--Order=(.*)/ ) {
643
                    $order = $1;
644
                } elsif ( /^--AllowDup$/ ) {
645
                    $allowdup = 1;
646
                } elsif ( /^--NoAllowDup$/ ) {
647
                    $allowdup = 0;
648
                } elsif ( /^--NoWarn$/ ) {
649
                    $nowarn = 1;
650
                } elsif ( /^--Warn$/ ) {
651
                    $nowarn = 0;
652
                } elsif ( /^--if/ ) {
653
                    push @conds, $_;
654
                } else {
655
                    $arg .= $_;         # unknown
656
                }
657
            }
658
 
659
            $arg .= ",--Order=$order"       if ( $order );
660
            $arg .= ",--NoWarn"             if ( $nowarn );
661
            $arg .= ",--AllowDup"           if ( $allowdup );
662
            $arg .= ",$x_conds"             if ( $x_conds );
663
            $arg .= ",". join(',', @conds)  if ( @conds );
664
        }
665
        else
666
        {                               # other options etc
667
            $arg = $_;
668
        }
669
 
670
        push @$libs, $arg;              # push cooked argument
671
    }
672
}
673
 
674
 
675
sub LibProcess
676
{
677
    my ($libs) = @_;
678
    my (@newlibs, @ordered_newlibs);
679
    my ($order, @cond, %librecipes, %libstatus);
680
 
681
    #
682
    #   Only process the library specification if arguments/attributes
683
    #   are encountered .. compat with older makefile's.
684
    #
685
    my ($attrs) = 0;
686
 
687
    #   use Data::Dumper;
688
    #   $Data::Dumper::Purity = 1;
689
    #   ::Debug "# Uncooked library list";
690
    #   ::Debug Dumper( $libs );
691
 
692
    $order = 1;                                 # physical order start @ 1
693
    @cond = ();
694
 
695
    foreach (@$libs)
696
    {
697
        my ($libname, $class, $fdup, $fnowarn, @params);
698
 
699
        $libname = "";                          # library name and class
700
        $class = "User";                        # deafult class
701
        $fdup = 0;                              # default, remove duplicates
702
        $fnowarn = 0;
703
 
704
        if ( /^--if(.*)/ )
705
        {                                       # Conditional (for next)
706
            ::Warning( "Stray --if '$1' within library specification -- ignored" )
707
                if ( @cond );
708
            @cond = ( $_ );
709
            $attrs++;
710
            next;
711
        }
712
 
713
        if ( /^-[lL].*/ )
714
        {                                       # Library
715
            my (@args) = split( ',', $_ );      # split specification
716
 
717
            foreach (@args) {
718
                if ( /^-([lL])(.*)/ ) {         # Library
719
                    if ( $::ScmTargetHost eq "Unix" ) {
720
                        $libname = "lib$2";     # .. prefix lib
721
                        $libname =~ s/^liblib/lib/;
722
                    } else {
723
                        $libname = $2;          # .. just stripped name
724
                    }
725
                    $libname .= "\$(GBE_TYPE)"  # .. append GBE_TYPE
726
                        if ( $1 eq "l" );
727
 
728
                    push @params, $libname;
729
 
730
                } else {                        # Attribute/options
731
                    if ( /^--Order=(.*)/ ) {    # .. sort using 'class'
732
                        if ( exists $IfPkgOrdering{$1} )
733
                        {
734
                            $class = $1;
735
                        }
736
                        else
737
                        {
738
                            ::Warning( "Lib '$libname' has unknown class '$1'" );
739
                        }
740
 
741
 
742
                    } elsif ( /^--AllowDup$/ ) {# .. allow duplicate images
743
                        $fdup = 1;
744
 
745
                    } elsif ( /^--NoWarn$/ ) {  # .. disable warnings
746
                        $fnowarn = 1;
747
 
748
                    } elsif ( /^--if(.*)/ ) {   # .. conditional(s)
749
                        push @cond, $_;
750
 
751
                    } else {                    # .. other "parameters"
752
                        push @params, $_;
753
                    }
754
 
755
                    $attrs++;
756
                }
757
            }
758
 
759
            #
760
            #   Convert text class name to an ordered number to assist in sorting
761
            #
762
            $class = $IfPkgOrdering{ $class };
763
        }
764
        else
765
        {                                       # Anything else
766
            push @params, $_;
767
        }
768
 
769
        my ($recipe) = {
770
                CLASS   => $class,              # logical class, prim key
771
                ORDER   => $order,              # physical order, 2nd key
772
                LIBNAME => $libname,            # library name (if any)
773
                FDUP    => $fdup,               # duplicate flag
774
                FNOWARN => $fnowarn,            # no-warning flag
775
                CONDS   => [ @cond ],           # optional conditional(s)
776
                PARAMS  => [ @params ],         # parameters
777
            };
778
 
779
        push @newlibs, $recipe;                 # push recipe
780
        push @{$librecipes{$libname}}, $recipe  # plus index using $name
781
            if ( $libname ne "" );
782
 
783
        @cond = ();
784
        $order++;
785
    }
786
 
787
    #   ::Debug3 "# Cooked library list";
788
    #   ::Debug3 Dumper( @newlibs );
789
 
790
#   Parse the library list and determine the status and correct
791
#   handling of any duplicate images.
792
#..
793
    foreach my $name (keys %librecipes)
794
    {
795
        if ( scalar( @{$librecipes{$name}} ) > 1 )
796
        {
797
            my ($class, $classerr, $dup, $nowarn);
798
 
799
            foreach my $recipe (@{$librecipes{$name}})
800
            {
801
                $classerr = 1                   # test for conflicts
802
                    if ( defined($class) && $class ne $recipe->{CLASS} );
803
 
804
                $class = $recipe->{CLASS};
805
 
806
                $dup = $recipe->{FDUP}          # accumulate
807
                    if ( !defined($dup) || $recipe->{FDUP} );
808
 
809
                $nowarn = $recipe->{FNOWARN}    # accumulate
810
                    if ( !defined($nowarn) || $recipe->{FNOWARN} );
811
            }
812
 
813
            my ($stat) = {};
814
 
815
            $stat->{SEEN} = 0;
816
            $stat->{DUP} = $dup;
817
            $stat->{NOWARN} = $nowarn;
818
            $stat->{CLASSERR} = 1 if (defined($classerr));
819
            $libstatus{$name} = $stat;
820
        }
821
    }
822
 
823
#   Sort the library list
824
#
825
    @ordered_newlibs =                          # sort by class/order
826
        sort {
827
            ($a->{CLASS} ne "" && $b->{CLASS} ne "" &&
828
                    $a->{CLASS} cmp $b->{CLASS}) ||
829
            $a->{ORDER} <=> $b->{ORDER}
830
        } @newlibs;
831
 
832
    #   ::Debug3 "# Sorted library list";
833
    #   ::Debug3 Dumper( @ordered_newlibs );
834
 
835
#   Now built the final list, removing duplicates (if required)
836
#
837
    @$libs = ();                                # zap libraries
838
 
839
    foreach my $newlib (@ordered_newlibs)
840
    {
841
        my ($name) = $newlib->{LIBNAME};
842
 
843
        if ($attrs && defined($libstatus{$name}))
844
        {                                       # two or more entries
845
            my ($stat) = $libstatus{$name};
846
 
847
            if ( $stat->{SEEN}++ == 0 )
848
            {                                   # first image
849
                if ( ! $stat->{NOWARN} )
850
                {                               # .. warnings ?
851
                    if ( defined($stat->{CLASSERR}) )
852
                    {                           # .. class conflict
853
                        my (@classes);
854
 
855
                        foreach my $recipe (@{$librecipes{$name}}) {
856
                            ::UniquePush( \@classes, $recipe->{CLASS} );
857
                        }
858
                        ::Warning( "Lib '$name' has multiple classes\n\t" .
859
                            ::CommifySeries( ClassNumToText(@classes) ) );
860
                    }
861
 
862
                    my ($count) = scalar( @{$librecipes{$name}} );
863
 
864
                    ::Warning( "Lib '$name' appeared $count times, ".
865
                               "duplicate" . ($count > 2 ? "s":""). " removed" )
866
                        if ($stat->{DUP} == 0);
867
                }
868
            }
869
            else
870
            {                                   # remove duplicate(s) ?
871
                next if ($stat->{DUP} == 0);
872
            }
873
        }
874
 
875
        my ($spec);
876
 
877
        $spec = join( ',', @{$newlib->{PARAMS}} );
878
        $spec .= "\n\t\t" . join( "\n\t\t", @{$newlib->{CONDS}} )
879
            if ( @{$newlib->{CONDS}} );
880
 
881
        push @$libs, $spec;
882
    }
883
 
884
    #   ::Debug "# Final library list";
885
    #   ::Debug Dumper( $libs );
886
}
887
 
888
 
889
sub ExportDepend
890
{
891
    #
892
    #   Create the dependancy data structure
893
    #   Its easier to dump a complete structure
894
    #
895
    my %ScmBuildPkgDepend;
896
    foreach my $platform ( keys %::ScmBuildPkgRules )
897
    {
898
        foreach my $package ( @{$::ScmBuildPkgRules{$platform}} )
899
        {
900
            my %entry;
901
            $entry{NAME}        = $package->{'NAME'};
902
            $entry{VERSION}     = $package->{'VERSION'};
903
            $entry{DNAME}       = $package->{'DNAME'};
904
            $entry{DVERSION}    = $package->{'DVERSION'};
905
            $entry{DPROJ}       = $package->{'DPROJ'};
906
 
907
            push @{$ScmBuildPkgDepend{$platform}}, \%entry;
908
        }
909
    }
910
 
911
 
912
    my $fh = ::ConfigurationFile::New( "DPACKAGE.CFG" );
913
    $fh->Header( "makelib (Version $::ScmVersion)",
914
                                "DPACKAGE configuration file" );
915
    $fh->DumpData(
916
        "# Dependancy list.\n#\n",
917
        "ScmBuildPkgDepend", \%ScmBuildPkgDepend );
918
 
919
    $fh->Close(1);
920
}
921
 
922
 
923
###############################################################################
924
#   BASE_Toolset ---
925
#       Default interface.
926
#
927
#..
928
 
929
package BASE_Toolset;
930
 
931
MakeIf::Push( "BASE_Toolset" );                 # root of object stack
932
 
933
sub Spawn
934
{
935
    my ($obclass) = shift;
936
    my ($class) = ref($obclass) || $obclass;
937
    my ($self) = {};
938
 
939
    ::Debug2( "\tBASE_Toolset->Spawn()" );
940
    bless($self, $class);
941
    return ($self);
942
}
943
 
944
 
945
sub Preprocess
946
{
947
    my ($self) = shift;
948
 
949
    ::Debug2( "BASE_Toolset->Preprocess()" );
950
    ::ToolsetPreprocess()                       # optional toolset interface
951
        if ( defined &::ToolsetPreprocess );
952
}
953
 
954
 
955
sub Postprocess
956
{
957
    my ($self) = shift;
958
 
959
    ::Debug2( "BASE_Toolset->Postprocess()" );
960
    ::ToolsetPostprocess()                      # optional toolset interface
961
        if ( defined &::ToolsetPostprocess );
962
}
963
 
964
 
965
sub CTAGS
966
{
967
    ::ToolsetCTAGS()                            # optional toolset interface
968
        if ( defined &::ToolsetCTAGS );
969
}
970
 
971
 
972
sub CCDepend
973
{
974
    my ($self) = shift;
975
 
976
    ::Debug2( "BASE_Toolset->CCDepend()" );
977
    ::Error ("BASE_Toolset does not support C file dependency generation" )
978
        unless ( defined &::ToolsetCCDepend );
979
    ::ToolsetCCDepend( @_ );                    # toolset
980
}
981
 
982
 
983
sub CXXDepend
984
{
985
    my ($self) = shift;
986
 
987
    ::Debug2( "BASE_Toolset->CXXDepend()" );
988
    ::Error ("BASE_Toolset does not support C++ dependency generation" )
989
        unless ( defined &::ToolsetCXXDepend );
990
    ::ToolsetCXXDepend( @_ );                   # toolset
991
}
992
 
993
 
994
sub CC
995
{
996
    my ($self) = shift;
997
    my ($source, $obj, $pArgs) = @_;
998
 
999
    ::Debug2( "BASE_Toolset->CC($source)" );
1000
    ::Error ("BASE_Toolset does not support C compilation" )
1001
        unless ( defined &::ToolsetCC );
1002
    ::ToolsetCC( @_ );                          # toolset
1003
}
1004
 
1005
 
1006
sub CXX
1007
{
1008
    my ($self) = shift;
1009
    my ($source, $obj, $pArgs) = @_;
1010
 
1011
    ::Debug2( "BASE_Toolset->CXX($source)" );
1012
    ::Error ("BASE_Toolset does not support C++ compilation" )
1013
        unless ( defined &::ToolsetCXX );
1014
    ::ToolsetCXX( @_ );                         # toolset
1015
}
1016
 
1017
 
1018
sub AS
1019
{
1020
    my ($self) = shift;
1021
    my ($source, $obj, $pArgs) = @_;
1022
 
1023
    ::Debug2( "BASE_Toolset->AS($source)" );
1024
    ::Error ("BASE_Toolset does not support assembler files" )
1025
        unless ( defined &::ToolsetAS );
1026
    ::ToolsetAS( @_ );                          # toolset
1027
}
1028
 
1029
 
1030
sub EXT
1031
{
1032
    my ($self) = shift;
1033
 
1034
    ::Debug2( "BASE_Toolset->EXT()" );
1035
    return ::ToolsetEXT( @_ )                   # optional toolset interface
1036
        if ( defined &::ToolsetEXT );
1037
    return 0;                                   # default not supppored
1038
}
1039
 
1040
 
1041
sub AR
1042
{
1043
    my ($self) = shift;
1044
    my ($name, $pArgs, $pObjs) = @_;
1045
 
1046
    ::Debug2( "BASE_Toolset->AR($name)" );
1047
    ::Error ("BASE_Toolset does not support library files" )
1048
        unless ( defined &::ToolsetAR );
1049
 
1050
    ProcessArgs ( "", @_ );                     # Proccess arguments
1051
    ::ToolsetAR( @_ );                          # toolset
1052
}
1053
 
1054
 
1055
sub ARLINT
1056
{
1057
    my ($self) = shift;
1058
    my ($name, $pArgs, $pObjs) = @_;
1059
 
1060
    my ($lname) = "\$(LIBDIR)/$name\$(GBE_TYPE)";
1061
    my ($ltarget) = "lib_$name\_lint";
1062
    my (@LIBCSRC, @LIBCXXSRC) = ();
1063
    my ($srcfile) = "";
1064
 
1065
    ::Debug2( "BASE_Toolset->ARLINT($name)" );
1066
    ::Error ("BASE_Toolset does not support library files" )
1067
        unless ( defined &::ToolsetAR );
1068
 
1069
    foreach (@$pObjs) {
1070
        $_ =~ s/^\$\(OBJDIR\)\///g;             # remmove OBJDIR
1071
 
1072
        if ( ($srcfile = $::OBJSOURCE{ $_ }) )
1073
        {
1074
            my( $quoted_srcfile ) = quotemeta( $srcfile );
1075
 
1076
            if ( grep /^$quoted_srcfile$/, @::CSRCS ) {
1077
                push( @LIBCSRC, $srcfile );
1078
 
4728 dpurdie 1079
            } elsif ( grep /^$quoted_srcfile$/, @::CXXSRCS ) {
271 dpurdie 1080
                push( @LIBCXXSRC, $srcfile );
1081
 
1082
            }
1083
        }
1084
    }
1085
 
1086
    ::MakePrint(  "
1087
#.. Lint library ($name)
1088
 
1089
.PHONY:		$ltarget
1090
$ltarget:	LIBBASE = $name
1091
$ltarget:	LIBNAME = $lname
1092
" );
1093
 
1094
    ::MakeDefEntry ( "$ltarget:","LIBCSRC =", \@LIBCSRC );
1095
    ::MakeDefEntry ( "$ltarget:","LIBCXXSRC =", \@LIBCXXSRC );
1096
 
1097
    if ( defined ( &::ToolsetARLINT ) ) {
1098
        ::MakePrint( "$ltarget:" );
1099
        ::ToolsetARLINT( $name, $pArgs, $pObjs, $ltarget, \@LIBCSRC, \@LIBCXXSRC );
1100
 
1101
    } else {
1102
        ::MakePrint( "$ltarget:	\
6177 dpurdie 1103
	\@echo '[\$(LIBNAME)] linting not supported..'\n" );
271 dpurdie 1104
    }
1105
 
1106
    ::MakePrint( "\n" );
1107
}
1108
 
1109
 
1110
sub ARMerge
1111
{
1112
    my ($self) = shift;
1113
    my ($name, $pArgs, $pLibs) = @_;
1114
 
1115
    ::Debug2( "BASE_Toolset->ARMERGE($name)" );
1116
    ::Error ("BASE_Toolset does not support library file merging" )
1117
        unless ( defined &::ToolsetARMerge );
1118
    ::ToolsetARMerge( @_ );                     # toolset
1119
}
1120
 
1121
 
1122
sub SHLD
1123
{
1124
    my ($self) = shift;
1125
    my ($name, $pArgs, $pObjs, $pLibs) = @_;
1126
    my ($i);
1127
 
1128
    ::Debug2( "BASE_Toolset->SHLD($name)" );
1129
    ::Error ("BASE_Toolset does not support shared libraries" )
1130
        unless ( defined &::ToolsetSHLD );
1131
 
1132
    ProcessArgs ( 'Using', @_ );                # Proccess arguments
1133
 
1134
    MakeIf::LibProcess( $pLibs );               # cook libraries
1135
 
1136
    ::Debug3( " args: @$pArgs" );
1137
    ::Debug3( " objs: @$pObjs" );
1138
    ::Debug3( " libs: @$pLibs" );
1139
 
1140
    ::ToolsetSHLD( @_ );                        # toolset
1141
}
1142
 
1143
 
1144
sub SHLDLINT
1145
{
1146
    my ($self) = shift;
1147
    my ($name, $pArgs, $pObjs, $pLibs) = @_;
1148
 
1149
    my ($lname) = "\$(LIBDIR)/$name\$(GBE_TYPE)";
1150
    my ($ltarget) = "shlib_$name\_lint";
1151
    my (@SHLIBCSRC, @SHLIBCXXSRC) = ();
1152
    my ($srcfile) = "";
1153
 
1154
    ::Debug2( "BASE_Toolset->SHLDLINT($name)" );
1155
    ::Error ("BASE_Toolset does not support shared libraries" )
1156
        unless ( defined &::ToolsetSHLD );
1157
 
1158
    foreach (@$pObjs) {
1159
        $_ =~ s/^\$\(OBJDIR\)\///g;             # remmove OBJDIR
1160
 
1161
        if ( ($srcfile = $::OBJSOURCE{ $_ }) )
1162
        {
1163
            my( $quoted_srcfile ) = quotemeta( $srcfile );
1164
 
1165
            if ( grep /^$quoted_srcfile$/, @::CSRCS ) {
1166
                push( @SHLIBCSRC, $srcfile );
1167
 
4728 dpurdie 1168
            } elsif ( grep /^$quoted_srcfile$/, @::CXXSRCS ) {
271 dpurdie 1169
                push( @SHLIBCXXSRC, $srcfile );
1170
 
1171
            }
1172
        }
1173
    }
1174
 
1175
    ::MakePrint(  "
1176
#.. Lint shared library ($name)
1177
 
1178
.PHONY:		$ltarget
1179
$ltarget:	SHLIBBASE = $name
1180
$ltarget:	SHLIBNAME = $lname
1181
" );
1182
 
1183
    ::MakeDefEntry ( "$ltarget:","SHLIBCSRC =", \@SHLIBCSRC );
1184
    ::MakeDefEntry ( "$ltarget:","SHLIBCXXSRC =", \@SHLIBCXXSRC );
1185
 
1186
    if ( defined ( &::ToolsetSHLDLINT ) ) {
1187
        ::MakePrint( "$ltarget:" );
1188
        ::ToolsetSHLDLINT( $name, $pArgs, $pObjs, $pLibs, $ltarget, \@SHLIBCSRC, \@SHLIBCXXSRC );
1189
 
1190
    } else {
1191
        ::MakePrint( "$ltarget:	\
6177 dpurdie 1192
	\@echo '[\$(SHLIBNAME)] linting not supported..'\n" );
271 dpurdie 1193
    }
1194
 
1195
    ::MakePrint( "\n" );
1196
}
1197
 
1198
 
1199
sub LD
1200
{
1201
    my ($self) = shift;
1202
    my ($name, $pArgs, $pObjs, $pLibs) = @_;
1203
    my ($i);
1204
 
1205
    ::Debug2( "BASE_Toolset->LD($name)" );
1206
    ::Error ("BASE_Toolset does not support program generation" )
1207
        unless ( defined &::ToolsetLD );
1208
 
4728 dpurdie 1209
    ProcessArgs ( 'Using', @_ );                # Proccess arguments
271 dpurdie 1210
 
1211
    MakeIf::LibProcess( $pLibs );               # cook libraries
1212
 
1213
    ::Debug3( " args: @$pArgs" );
1214
    ::Debug3( " objs: @$pObjs" );
1215
    ::Debug3( " libs: @$pLibs" );
1216
 
1217
    ::ToolsetLD( @_ );                          # toolset
1218
}
1219
 
1220
 
1221
sub LDLINT
1222
{
1223
    my ($self) = shift;
1224
    my ($name, $pArgs, $pObjs, $pLibs) = @_;
1225
 
1226
    my ($pname) = "\$(BINDIR)/$name";
1227
    my ($ptarget) = "prog_$name\_lint";
1228
    my (@PROGCSRC, @PROGCXXSRC) = ();
1229
    my ($srcfile) = "";
1230
 
1231
    ::Debug2( "BASE_Toolset->LDLINT($name)" );
1232
    ::Error ("BASE_Toolset does not support program generation" )
1233
        unless ( defined &::ToolsetLD );
1234
 
1235
    foreach (@$pObjs) {
1236
        $_ =~ s/^\$\(OBJDIR\)\///g;             # remmove OBJDIR
1237
 
1238
        if ( ($srcfile = $::OBJSOURCE{ $_ }) )
1239
        {
1240
            my( $quoted_srcfile ) = quotemeta( $srcfile );
1241
 
1242
            if ( grep /^$quoted_srcfile$/, @::CSRCS ) {
1243
                push( @PROGCSRC, $srcfile );
1244
 
4728 dpurdie 1245
            } elsif ( grep /^$quoted_srcfile$/, @::CXXSRCS ) {
271 dpurdie 1246
                push( @PROGCXXSRC, $srcfile );
1247
 
1248
            }
1249
        }
1250
    }
1251
 
1252
    ::MakePrint(  "
1253
#.. Lint program ($name)
1254
 
1255
.PHONY:		$ptarget
1256
$ptarget:	PROGBASE = $name
1257
$ptarget:	PROGNAME = $pname
1258
" );
1259
 
1260
    ::MakeDefEntry ( "$ptarget:","PROGCSRC =", \@PROGCSRC );
1261
    ::MakeDefEntry ( "$ptarget:","PROGCXXSRC =", \@PROGCXXSRC );
1262
 
1263
    if ( defined ( &::ToolsetLDLINT ) ) {
1264
        ::MakePrint( "$ptarget:" );
1265
        ::ToolsetLDLINT( $name, $pArgs, $pObjs, $pLibs, $ptarget, \@PROGCSRC, \@PROGCXXSRC );
1266
 
1267
    } else {
1268
        ::MakePrint( "$ptarget:	\
6177 dpurdie 1269
	\@echo '[\$(PROGNAME)] linting not supported..'\n" );
271 dpurdie 1270
    }
1271
 
1272
    ::MakePrint( "\n" );
1273
}
1274
 
1275
#-------------------------------------------------------------------------------
1276
# Function        : PROJECT
1277
#
1278
# Description     : Invoke the underlying toolset functions to construct a
1279
#                   project
1280
#
1281
# Inputs          : $pProject       - Reference to the project data
1282
#
1283
# Returns         :
1284
#
1285
sub PROJECT
1286
{
1287
    my( $self, $pProject) = @_;
1288
    my $name = $pProject->{name};
1289
 
1290
    ::Debug2( "BASE_Toolset->PROJECT($name)" );
1291
    ::Error ("BASE_Toolset does not support Project generation" )
1292
        unless ( defined &::ToolsetPROJECT );
1293
 
1294
    #
1295
    #   Sanity test the Toolset PROJECT
1296
    #   Only the JAVA toolset will handle ANT projects
1297
    #
1298
    my $ptype = $pProject->{type} ;
1299
    if ( $ptype )
1300
    {
1301
        my $type = $::ToolsetPROJECT_type || '';
1302
        ::Error ("BASE_Toolset does not support Project generation of type: $ptype " )
1303
            unless ( $type eq $ptype );
1304
    }
1305
 
5411 dpurdie 1306
    ::Error ("BASE_Toolset does not support Automated Unit Tests" ) 
1307
        if ($pProject->{'autotest'} && ! $::ScmToolsetProperties{'AutoUnitTests'}); 
1308
    ::Error ("BASE_Toolset does not support Manual Unit Tests" ) 
1309
        if ($pProject->{'unittest'} && ! $::ScmToolsetProperties{'UnitTests'});
1310
 
271 dpurdie 1311
    #
1312
    #   Generate Phony target names
1313
    #   The toolset MUST provide the targets
1314
    #
1315
    ::MakePrint( "PHONY:\tProjectClean_$name\n" );
1316
    ::MakePrint( "PHONY:\tProject_$name\n" );
1317
    ::MakePrint( "PHONY:\tProjectATest_$name\n" ) if ($pProject->{'autotest'});
1318
    ::MakePrint( "PHONY:\tProjectUTest_$name\n" ) if ($pProject->{'unittest'});
1319
    ::MakePrint( "\n" );
1320
 
1321
    #
1322
    #   Projects may be specific to debug or production
1323
    #
1324
    my $conditional;
1325
    $conditional = 'ifeq'  if ($pProject->{'Debug'});
1326
    $conditional = 'ifneq' if ($pProject->{'Prod'});
1327
    if ( $conditional )
1328
    {
1329
        ::MakePrint( "$conditional \"\$(DEBUG)\" \"1\"\n" );
1330
    }
1331
 
1332
    #
1333
    #   Invoke toolset specific function to create the desired targets
1334
    #
1335
    ::ToolsetPROJECT( $pProject->{name},
1336
                      $pProject->{project},
1337
                      $pProject->{options},
1338
                      $pProject->{'autotest'},
1339
                      $pProject->{'unittest'},
6353 dpurdie 1340
                      $pProject->{'generated'},
1341
                      $pProject
271 dpurdie 1342
                       );
1343
 
1344
    #
1345
    #   Complete any conditional process
1346
    #
1347
    if ( $conditional )
1348
    {
1349
        ::MakePrint( "else\n\n" );
1350
        ::MakePrint( "ProjectClean_$name:\n" );
1351
        ::MakePrint( "Project_$name:\n" );
1352
        ::MakePrint( "ProjectATest_$name:\n" ) if ($pProject->{'autotest'});
1353
        ::MakePrint( "ProjectUTest_$name:\n" ) if ($pProject->{'unittest'});
1354
        ::MakePrint( "\nendif\n" );
1355
    }
1356
 
1357
    #
1358
    #   If this project does contain a unit test, then the name of the target
1359
    #   that will run the unit test must be added to a list
1360
    #
1361
    push @::TESTPROJECT_TO_ARUN, "ProjectATest_$name" if ($pProject->{'autotest'});
5035 dpurdie 1362
    push @::TESTPROJECT_TO_URUN, "ProjectATest_$name" if ($pProject->{'autotest'});
5411 dpurdie 1363
    push @::TESTPROJECT_TO_URUN, "ProjectUTest_$name" if ($pProject->{'unittest'});
271 dpurdie 1364
}
1365
 
1366
 
1367
#-------------------------------------------------------------------------------
1368
# Function        : TESTFRAMEWORK
1369
#
1370
# Description     : Invoke the underlying toolset functions to construct a
1371
#                   Test Frame Work
1372
#
1373
#                   Done by manipulating entries in the HASH that is passed
1374
#                   into the FrameWork Support functionn
1375
#
1376
# Inputs          : $pEntry       - Reference to the test data
1377
#
1378
# Returns         :
1379
#
1380
sub TESTFRAMEWORK
1381
{
1382
    my( $self, $pEntry, @args) = @_;
1383
    my $name = $pEntry->{framework};
1384
    my $fnc = 'ToolsetTESTFRAMEWORK_'. uc($name);
1385
    my $fref = UNIVERSAL::can ( '::main', $fnc );
1386
    ::Debug2( "BASE_Toolset->TestFrameWork($name)" );
1387
    ::Error ("BASE_Toolset does not support Test Frame Work generation: $name" )
1388
        unless ( $fref );
1389
 
1390
    &$fref( $pEntry, @args );          # Invoke the Function
1391
}
1392
 
1393
#sub LDUsing
1394
#{
1395
#    my ($self) = shift;
1396
#    my ($using, $name, $isshared, $pObjs, $pLibs) = @_;
1397
#
1398
#    ::Debug2( "BASE_Toolset->LDUsing($using, $isshared, $name)" );
1399
#
1400
#    MakeIf::LibUsing( $name, $using, $pLibs );
1401
#}
1402
 
1403
#-------------------------------------------------------------------------------
1404
# Function        : ProcessArgs
1405
#
1406
# Description     : Process arguments for the program and library building commands
1407
#                   Processes options:
1408
#                       --Using(XXX),[options]
1409
#                       --Exclude(XXX,XXX,XXX)
1410
#                       --ExcludeLIB(XXX,XXX,XXX)
1411
#
1412
# Inputs          : $mode       - Using == Allow 'Using'
1413
#                   $name       - Name of the program/library
1414
#                   $pArgs      - Ref to an array of arguments
1415
#                   $pObjs      - Ref to an array of objects
1416
#                   $pLibs      - Ref to an array of libraries (Optional)
1417
#
1418
#                   Note: Argument order to assist caller
1419
#
1420
# Returns         : Nothing directly
1421
#                   Massages arrays directly
1422
#
1423
sub ProcessArgs
1424
{
1425
    my ($mode, $name, $pArgs, $pObjs, $pLibs) = @_;
1426
    ::Debug2( "BASE_Toolset->ProcessArgs(@$pArgs)" );
1427
 
1428
    my @rArgs;
1429
 
1430
    my $i;
1431
    for ($i = 0; $i < scalar @$pArgs; $i++)
1432
    {
1433
        $_ = $pArgs->[$i];
1434
 
1435
        if ( $mode && /^--Using\((.*)\)(.*)$/)  # --Using(XXX)[,options]
1436
        {
1437
            MakeIf::LibUsing( $name, "$1$2", $pLibs );
1438
 
1439
#::DebugDumpData("IfPkgLibaries",\%IfPkgLibaries );
1440
#::DebugDumpData("pLibs",\$pLibs );
1441
        }
1442
        elsif (/^--Exclude\((.*)\)$/)           # --Exclude(Obj,Obj...)
1443
        {
1444
            #
1445
            #   Exclude specified object files
1446
            #   Note: Maintain the order of the object files
1447
            #
1448
            my %exclude;
1449
            my @retain = ();
1450
 
1451
            @exclude{split( ',', $1 )} = ();
1452
 
1453
            foreach (@$pObjs)
1454
            {
1455
                (my $objfile = $_) =~ s~.*/~~;  # Remove Shared lib object directory
1456
 
1457
                push @retain, $_
1458
                    unless (exists $exclude{$objfile} );
1459
            }
1460
            @$pObjs = @retain;
1461
            ::Debug3( "BASE_Toolset->ProcessArgs. OBJS: @retain)" );
1462
        }
1463
        elsif (/^--ExcludeLib\((.*)\)$/)        # --ExcludeLib(Lib,Lib...)
1464
        {
1465
            #
1466
            #   Exclude specified library files
1467
            #   Note: Maintain the order of the library files
1468
            #
1469
            my %exclude;
1470
            my @retain_libs = ();
1471
 
1472
            @exclude{split( ',', $1 )} = ();
1473
 
1474
            foreach (@$pLibs)
1475
            {
1476
                m~-[Ll]([^,]*)~;                # Extract library name
1477
                my $libfile = $1;
1478
                push @retain_libs, $_
1479
                    unless (exists $exclude{$libfile} );
1480
            }
1481
            @$pLibs = @retain_libs;
1482
            ::Debug3( "BASE_Toolset->ProcessArgs. LIBS: @retain_libs)" );
1483
        }
1484
        else
1485
        {
1486
            #
1487
            #   Unknown option
1488
            #   Retain to be processed later
1489
            #
1490
            push @rArgs, $_;
1491
        }
1492
    }
1493
 
1494
    #
1495
    #   Pass unprocessed arguments back to the user
1496
    #
1497
    @$pArgs = @rArgs;
1498
}
1499
 
1500
1;
1501