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