Subversion Repositories DevTools

Rev

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