Subversion Repositories DevTools

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
227 dpurdie 1
# -*- mode: perl; tabs: 8; indent-width: 4; show-tabs: yes; -*-
2
#
3
# Module name   : GCC
4
# Module type   : Makefile system
5
# Compiler(s)   : ANSI C
6
# Environment(s): GCC
7
#
8
# Description:
9
#       GCC C/C++ toolset
10
#
11
#............................................................................#
12
 
13
use strict;
14
use warnings;
15
 
16
##############################################################################
17
#   Configuration information
18
#   Cross reference from CrossCompiler Alias to actual paths
19
#   Structure:
20
#   Hash reference: Array of toolchain information
369 dpurdie 21
#       Mandatory
22
#          ROOT             => Root of compiler
23
#          BASE             => Base for binaries
24
#       Optional
25
#          CC_OPTS          => Additonal Compiler options
26
#          UNCONTROLLED     => Boolean to create warning
27
 
227 dpurdie 28
my %ToolsetConfig = (
29
 
369 dpurdie 30
    'i386-unknown-linux-gnu'    => {
31
        ROOT => '/opt/crosstool/gcc-4.1.1-glibc-2.5/i586-unknown-linux-gnu',
32
        BASE => 'bin/i586-unknown-linux-gnu-',
33
    },
227 dpurdie 34
 
369 dpurdie 35
    'arm-9tdmi-linux-gnu'       => {
36
        ROOT => '/opt/crosstool/gcc-4.1.1-glibc-2.5/arm-9tdmi-linux-gnu',
37
        BASE => 'bin/arm-9tdmi-linux-gnu-'
38
        },
247 dpurdie 39
 
369 dpurdie 40
    'powerpc-603e-linux-gnu'    => {
41
       ROOT => '/opt/crosstool/gcc-4.1.1-glibc-2.5/powerpc-603e-linux-gnu',
42
       BASE => 'bin/powerpc-603e-linux-gnu-'
43
    },
337 dpurdie 44
 
369 dpurdie 45
    'arm-926ejs-linux-gnueabi'  => {
46
       ROOT => '/opt/crosstool/gcc-4.4.3-glibc-2.9/arm-926ejs-linux-gnueabi',
47
       BASE => 'bin/arm-926ejs-linux-gnueabi-',
48
       CC_OPTS => '-Wno-psabi',
49
    },
50
 
227 dpurdie 51
    #
52
    #   Old (not to be used) version of the embedded toolchain
53
    #   This was depricated in favor of gcc-4.1.1-glibc-2.5
54
    #   It is not possible to reproduce old packages using the old compiler
55
    #   This is a known issue
56
    #
369 dpurdie 57
    'i386-unknown-linux-gnu.glibc-2.3.2' => {
58
       ROOT => '/opt/crosstool/gcc-4.1.0-glibc-2.3.2/i386-unknown-linux-gnu',
59
       BASE => 'bin/i386-unknown-linux-gnu-'
60
    },
227 dpurdie 61
 
369 dpurdie 62
    'arm-9tdmi-linux-gnu.glibc-2.3.2' => {
63
       ROOT => '/opt/crosstool/gcc-4.1.0-glibc-2.3.2/arm-9tdmi-linux-gnu',
64
       BASE => 'bin/arm-9tdmi-linux-gnu-'
65
    },
227 dpurdie 66
 
67
    #
68
    #   Not too sure where this is used
69
    #
369 dpurdie 70
    'armv4l-unknown-linux-gcc' => {
71
       ROOT => '/opt/host/armv4l',
72
       BASE => 'bin/armv4l-unknown-linux-'
73
    },
227 dpurdie 74
 
75
    #
76
    #   The compiler for the current local machine
77
    #
369 dpurdie 78
    'i386-unknown-linux-gcc' => {
79
       ROOT => '/usr',
80
       BASE => 'bin/',
81
       UNCONTROLLED => 1,
82
    },
83
);
227 dpurdie 84
 
85
#
86
#   Cross reference from GCCTarget to GBE_MACHTYPE for which it can
87
#   build using the 'native gcc'. This is NOT the preferred mode of operation
88
#   as the compiler is not as controlled as the cross compilers.
89
#
90
my %NativeCompilers = (
91
    'Linux i386'       => 'linux_i386',
92
    );
93
 
94
##############################################################################
95
#   ToolsetInit()
96
#       Runtime initialisation
97
#
98
##############################################################################
99
 
100
ToolsetInit();
101
 
102
sub ToolsetInit
103
{
369 dpurdie 104
    my( $GCCTarget, $GCCToolchain, $GCCRoot, $GCCBin, $GCCAr, $GCCFlags );
227 dpurdie 105
    my( $arg_alias, $tools_found );
106
 
107
#.. Toolset configuration
108
#
109
    $::ScmToolsetVersion = "1.0.0";             # our version
110
    $::ScmToolsetGenerate = 0;                  # GEN generate optional
111
    $::ScmToolsetCompilerPath = 1;              # Exports Compiler path to makefile via SCM_COMPILERPATH
271 dpurdie 112
    $::ScmToolsetProgDependancies = 0;          # handle Prog dependancies myself
339 dpurdie 113
    $::ScmToolsetSoName = 1;                    # Shared library supports SoName
227 dpurdie 114
 
115
#.. Standard.rul requirements
116
#
117
    $::s = "asm";
118
    $::o = "o";
119
    $::so = "so";
120
    $::a = "a";
121
    $::exe = "";
122
 
123
#.. Parse arguments
124
#
125
    foreach $_ ( @::ScmToolsetArgs ) {
126
        if (/^--Target=(.*)/) {                 # OS Version
127
            $GCCTarget = "$1";
128
 
129
        } elsif (/^--CrossAlias=(.*)/) {        # CrossCompiler target-alias
130
            $arg_alias = $1;
131
 
132
        } else {
133
            Message( "gcc toolset: unknown option $_ -- ignored\n" );
134
        }
135
    }
136
 
137
    foreach $_ ( @::ScmPlatformArgs ) {
138
        if (/^--product=(.*)/) {                # GBE product
139
 
140
        } else {
141
            Message( "gcc toolset: unknown platform argument $_ -- ignored\n" );
142
        }
143
    }
144
 
145
    Error ("TOOLSET/gcc - Target undefined" )
146
        unless ($GCCTarget);
147
 
148
#.. Cross compile support
149
#
150
#   Toolchain=root,[bin]
151
#
152
    if ( $arg_alias )
153
    {
154
        if ( exists $ToolsetConfig{ $arg_alias } )
155
        {
369 dpurdie 156
            $GCCToolchain = $ToolsetConfig{ $arg_alias };
157
            $tools_found = (-d $GCCToolchain->{ROOT});
227 dpurdie 158
            Warning ("gcc toolset: CrossPlatform toolchain not found for: $arg_alias",
369 dpurdie 159
                     "Path: $GCCToolchain->{ROOT}" ) unless $tools_found;
227 dpurdie 160
        }
161
        else
162
        {
163
            Error("gcc toolset: CrossPlatform Alias not configured: $arg_alias");
164
        }
369 dpurdie 165
 
166
        Warning ("Uncontrolled toolchain used: $arg_alias")
167
            if ( exists($GCCToolchain->{UNCONTROLLED}) && $GCCToolchain->{UNCONTROLLED} );
227 dpurdie 168
    }
169
 
170
    #
171
    #   If no Cross compiler toolchain is found (preferred method), then attempt
172
    #   to match a native compiler. Only known targets allow a native build
173
    #
174
    unless ( $tools_found )
175
    {
176
        if ( exists ( $NativeCompilers{$GCCTarget} ))
177
        {
178
            if ( $NativeCompilers{$GCCTarget} eq $::GBE_MACHTYPE )
179
            {
180
                $tools_found = 1;
369 dpurdie 181
                $GCCToolchain = undef;
227 dpurdie 182
            }
183
        }
184
    }
185
 
186
    #
187
    #   Must have a toolset by now, either a cross compiler or Native
188
    #
189
    Error ("gcc toolset: Toolchain not found for: $GCCTarget" )
190
        unless ( $tools_found );
191
 
192
 
369 dpurdie 193
    if ( defined $GCCToolchain )
227 dpurdie 194
    {
195
        #
369 dpurdie 196
        #   Parse GCCToolchain. Potential parts to create
197
        #       GCCRoot     - Location to find the effective /usr/include directory
198
        #       GCCBin      - Path to the gcc executable
199
        #       GCCAr       - Path to the ar executable
200
        #       GCCFlags    - Additional compiler flags
227 dpurdie 201
        #
369 dpurdie 202
        $GCCRoot = $GCCToolchain->{ROOT};
203
        $GCCBin = '${GCC_ROOT}/' . $GCCToolchain->{BASE} . 'gcc';
204
        $GCCAr =  '${GCC_ROOT}/' . $GCCToolchain->{BASE} . 'ar';
205
        $GCCFlags = $GCCToolchain->{CC_OPTS};
227 dpurdie 206
    }
207
    else
208
    {
209
        $GCCRoot = "/usr";
210
        $GCCBin = "gcc";
211
        $GCCAr = "ar";
212
    }
213
 
214
#.. Define GCC environment
215
#
216
    PlatformDefine( "
217
#################################################
218
# GCC toolchain definitions 
219
#
220
#..");
369 dpurdie 221
    PlatformDefine( "GCC_TARGET         := $GCCTarget" );
222
    PlatformDefine( "GCC_ROOT           := $GCCRoot" );
223
    PlatformDefine( "GCC_CC             := $GCCBin" );
224
    PlatformDefine( "GCC_AR             := $GCCAr" );
227 dpurdie 225
    PlatformDefine( "" );
226
 
369 dpurdie 227
    PlatformDefine( "GCC_CFLAGS         := $GCCFlags" ) if defined $GCCFlags;
228
 
229
 
227 dpurdie 230
    #
231
    #   Required since this toolset advertises: ScmToolsetCompilerPath
232
    #
369 dpurdie 233
    PlatformDefine( "SCM_COMPILERPATH   := \$\{GCC_CC\}" );
234
    PlatformDefine( "" );
227 dpurdie 235
 
236
 
237
#.. Piece the world together
238
#
239
    Init( "gcc" );
240
    ToolsetDefines( "gcc.def" );
241
    ToolsetRules( "gcc.rul" );
242
    ToolsetRules( "standard.rul" );
243
 
244
#   Create a standard data structure
245
#   This is a hash of hashes
246
#       The first hash is keyed by CompileOption keyword
247
#       The second hash contains pairs of values to set or remove
248
#
249
    %::ScmToolsetCompilerOptions =
250
    (
251
        #
252
        #   Control the thread model to use
253
        #   This will affect the compiler options and the linker options
254
        #
255
        'staticprogs'        => { 'STATIC_PROGS' , '1' },      # Progams link staticlly
256
        'no_staticprogs'     => { 'STATIC_PROGS' , undef },    # Default
257
    );
258
 
259
    #
260
    #   Set default options
261
    #
262
    $::ScmCompilerOpts{'STATIC_PROGS'} = undef;
263
}
264
 
265
 
266
###############################################################################
267
#   ToolsetCC( $source, $obj, \@args )
268
#       This subroutine takes the user options and builds the rule(s)
269
#       required to compile the source file 'source' to 'obj'
270
#
271
###############################################################################
272
 
273
sub ToolsetCC
274
{
275
    my( $source, $obj, $pArgs ) = @_;
276
    my( $cflags, $file ) = "";
277
 
278
    foreach $_ ( @$pArgs ) {
279
        if (/--Shared$/) {                      # Building a 'shared' object
280
            $cflags  = "$cflags \$(SHCFLAGS)";
281
        } else {
282
            Message( "CC: unknown option $_ -- ignored\n" );
283
        }
284
    }
285
 
286
    MakePrint( "\n\t\$(CC)\n" );
287
    if ( $cflags )
288
    {                                           # object specific CFLAGS
289
        MakePadded( 4, "\$(OBJDIR)/$obj.$::o:" );
290
        MakePrint( "\tCFLAGS +=$cflags\n" );
291
    }
292
 
293
    $file = StripExt( $obj );                   # Metric working file
294
    ToolsetGenerate( "\$(OBJDIR)/$file.met" );
295
}
296
 
297
 
298
###############################################################################
299
#   ToolsetCCDepend( $depend, \@sources )
300
#       This subroutine takes the user options and builds the
301
#       rule(s) required to build the dependencies for the source
302
#       files 'sources' to 'depend'.
303
#
304
###############################################################################
305
 
306
sub ToolsetCCDepend
307
{
308
    MakePrint( "\t\$(CCDEPEND)\n" );
309
}
310
 
311
 
312
###############################################################################
313
#   ToolsetCXX( $source, $obj, \@args )
314
#       This subroutine takes the user options and builds the rule(s)
315
#       required to compile the source file 'source' to 'obj'
316
#
317
###############################################################################
318
 
319
sub ToolsetCXX
320
{
321
    my( $source, $obj, $pArgs ) = @_;
322
    my( $cflags, $file ) = "";
323
 
324
    foreach $_ ( @$pArgs ) {
325
        if (/--Shared$/) {                      # Building a 'shared' object
326
            $cflags  = "$cflags \$(SHCXXFLAGS)";
327
        } else {
328
            Message( "CXX: unknown option $_ -- ignored\n" );
329
        }
330
    }
331
 
332
    MakePrint( "\n\t\$(CXX)\n" );
333
    if ( $cflags )
334
    {                                           # object specific CFLAGS
335
        MakePadded( 4, "\$(OBJDIR)/$obj.$::o:" );
336
        MakePrint( "\tCXXFLAGS +=$cflags\n" );
337
    }
338
 
339
    $file = StripExt( $obj );                   # Metric working file
340
    ToolsetGenerate( "\$(OBJDIR)/$file.met" );
341
}
342
 
343
 
344
###############################################################################
345
#   ToolsetCXXDepend( $depend, \@sources )
346
#       This subroutine takes the user options and builds the
347
#       rule(s) required to build the dependencies for the source
348
#       files 'sources' to 'depend'.
349
#
350
###############################################################################
351
 
352
sub ToolsetCXXDepend
353
{
287 dpurdie 354
    ToolsetCCDepend();
227 dpurdie 355
}
356
 
357
 
358
###############################################################################
359
#   ToolsetAS( $source, $obj, \@args )
360
#       This subroutine takes the user options and builds the rule(s)
361
#       required to compile the source file 'source' to 'obj'
362
#
363
###############################################################################
364
 
365
sub ToolsetAS
366
{
367
    MakePrint( "\n\t\$(AS)\n" );
368
}
369
 
370
sub ToolsetASDepend
371
{
372
}
373
 
374
 
375
###############################################################################
376
#   ToolsetAR( $name, \@args, \@objs )
377
#       This subroutine takes the user options and builds the rules
378
#       required to build the library 'name'.
379
#
380
#   Arguments:
381
#       n/a
382
#
383
#   Output:
384
#       $(BINDIR)/name$.${a}:   .... ]
385
#           $(AR)
386
#
387
#       name_ld += ...  Linker command file
388
#           :
389
#
390
#       name_dp += ...  Dependency list
391
#           :
392
#
393
###############################################################################
394
 
395
sub ToolsetAR
396
{
397
    my( $name, $pArgs, $pObjs ) = @_;
398
 
399
#.. Parse arguments
400
#
401
    foreach $_ ( @$pArgs )
402
    {
403
        Message( "AR: unknown option $_ -- ignored\n" );
404
    }
405
 
406
#.. Target
407
#
408
    MakePrint( "#.. Library ($name)\n\n" );     # label
409
 
410
    MakeEntry( "\$(LIBDIR)/$name\$(GBE_TYPE).$::a:\t",
411
        "", "\\\n\t\t", ".$::o", @$pObjs );
412
 
413
#.. Build library rule (just append to standard rule)
414
#
415
    MakePrint( "\n\t\$(AR)\n\n" );
416
}
417
 
418
 
419
###############################################################################
420
#   ToolsetARMerge( $name, \@args, \@libs )
421
#       This subroutine takes the user options and builds the rules
422
#       required to build the library 'name' by merging the specified
423
#       libaries
424
#
425
#   Arguments:
426
#       --xxx                   No arguments currently defined
427
#
428
#   Output:
429
#       [ $(LIBDIR)/name$.${a}:   .... ]
430
#           ...
431
#
432
###############################################################################
433
 
434
sub ToolsetARMerge
435
{
436
    MakePrint( "\n\t\$(ARMERGE)\n\n" );
437
}
438
 
439
 
440
###############################################################################
289 dpurdie 441
#   ToolsetSHLD( $name, \@args, \@objs, \@libraries, $ver )
227 dpurdie 442
#       This subroutine takes the user options and builds the rules
339 dpurdie 443
#       required to link the Shared Library 'name'.
227 dpurdie 444
#
445
#   Arguments:
446
#   n/a
447
#
448
#   Output:
449
#       $(LIBDIR)/name:     $(LIBDIR)/shared
450
#           ln -s $shared $name
451
#
452
#       $(LIBDIR)/name.dep: $(GBE_OBJDIR)
453
#       $(LIBDIR)/name.dep: $(GBE_LIBDIR)
454
#       $(LIBDIR)/name.dep: $(GBE_PLATFORM).mk
455
#           $(SHLDDEPEND)
456
#
457
#       $(LIBDIR)/shared:   SHNAME=name
458
#       $(LIBDIR)/shared:   SHBASE=base
459
#       $(LIBDIR)/shared:   $(LIBDIR)/name.dep  \
460
#           $(OBJECTS)
461
#                           
462
#       ifneq "$(findstring $(IFLAG),23)" ""
463
#       -include            "$(LIBDIR)/name.dep"
464
#       endif
465
#
466
#       name_ld += ...
467
#           :
468
#
469
###############################################################################
470
 
471
sub ToolsetSHLD
472
{
289 dpurdie 473
    my( $name, $pArgs, $pObjs, $pLibs, $ver ) = @_;
339 dpurdie 474
    my( $linkname, $soname, $shared, $def, $def_pref, $multi_scan );
475
    my $sosuffix = '.' . $ver;
227 dpurdie 476
 
477
#.. Parse arguments
478
#
479
    foreach $_ ( @$pArgs )
480
    {
481
        if (/^--Def=(.*?)(\,(.*))?$/) {         # Library definition
482
            #
483
            #   Locate the Def file.
484
            #   If it is a generate file so it will be in the SRCS hash
485
            #   Otherwise the user will have to use Src to locate the file
486
            #
487
            $def = MakeSrcResolve($1);
488
            $def_pref = '';
489
            if ( $1 =~ m~\.def$~ ) {
490
                $def_pref = '--version-script='; # Old def file
491
            }
492
        } elsif ( /^--MultiScan/i ) {
493
            $multi_scan = 1;
494
 
495
        } elsif ( /^--NoMultiScan/i ) {
496
            $multi_scan = 0;
497
 
339 dpurdie 498
        } elsif ( /^--SoNameSuffix=(.*)/i ) {
499
            $sosuffix = $1;
500
 
227 dpurdie 501
        } else {
502
            Message( "SHLD: unknown option $_ -- ignored\n" );
503
        }
504
    }
505
 
339 dpurdie 506
#.. Various library names
227 dpurdie 507
#
339 dpurdie 508
    $linkname = "$name\$(GBE_TYPE).$::so";
509
    $shared = "$linkname.$ver";
510
    $soname = "$linkname$sosuffix";
227 dpurdie 511
 
512
#.. Cleanup rules
513
#
514
#   map     Map file
515
#   ln      Link from LIBDIR to BINDIR
516
#
261 dpurdie 517
    ToolsetGenerate( "\$(LIBDIR)/${name}.map" );
518
    ToolsetGenerate( "\$(LIBDIR)/${shared}" );
339 dpurdie 519
    ToolsetGenerate( "\$(BINDIR)/${soname}" );
227 dpurdie 520
 
521
#.. Build rules
522
#
523
#   name        Base name
524
#   shared      Library name, includes GBE_TYPE specification
525
#
526
    my ($io) = ToolsetPrinter::New();
335 dpurdie 527
    my $dep = $io->SetShldTarget($shared);
227 dpurdie 528
 
529
    $io->Label( "Shared library", $name );
339 dpurdie 530
    PackageShlibAddFiles( $name, "\$(LIBDIR)/$shared" );
531
 
227 dpurdie 532
    $io->Prt( "\$(LIBDIR)/${shared}:\tSHBASE=${name}\n" );
339 dpurdie 533
    $io->Prt( "\$(LIBDIR)/${shared}:\tSHNAME=${soname}\n" );
534
    $io->Prt( "\$(LIBDIR)/${shared}: \\\n\t\t${dep}" );
321 dpurdie 535
    $io->Entry( "", "", " \\\n\t\t", ".$::o", @$pObjs );
227 dpurdie 536
    $io->Prt( "\\\n\t\t$def" ) if($def);
321 dpurdie 537
    $io->Prt( "\n\t\$(SHLD)\n\n" );
538
 
227 dpurdie 539
 
339 dpurdie 540
#
541
#   Create soft links
542
#       'Real Name' to its 'Link Name'
543
#       'Real Name' to 'SoName' in the BINDIR (for testing I think)
544
#       'Real Name' to 'SoName' in the LIBDIR (if different)
545
#
546
    $io->Label( "Shared library Symbolic Links", $name );
547
    PackageShlibAddFiles( $name, "\$(LIBDIR)/$linkname" );
548
    $io->Prt( "\$(LIBDIR)/$linkname:\t\\\n" .
549
              "\t\t\$(GBE_BINDIR)\\\n" .
550
              "\t\t\$(LIBDIR)/${shared}\n" .
551
              "\t\$(AA_PRE)(rm -f \$@; ln -s ./$shared \$@)\n" .
552
              "\t\$(AA_PRE)(rm -f \$(BINDIR)/$soname; ln -s ../\$(LIBDIR)/$shared \$(BINDIR)/$soname)\n\n" );
553
 
554
    if ( $soname ne $shared && $soname ne $linkname)
555
    {
556
        $io->Label( "Shared library SoName Symbolic Links", $name );
557
        PackageShlibAddFiles( $name, "\$(LIBDIR)/$soname" );
558
        $io->Prt( "\$(LIBDIR)/$soname:\t\\\n" .
559
                  "\t\t\$(GBE_LIBDIR)\\\n" .
560
                  "\t\t\$(LIBDIR)/${shared}\n" .
561
                  "\t\$(AA_PRE)(rm -f \$@; ln -s ./$shared \$@)\n" );
562
    }
563
 
227 dpurdie 564
#.. Linker command file
565
#
566
#       Now the fun part... piecing together a variable $(name_shld)
567
#       which ends up in the command file.
568
#
339 dpurdie 569
    $io->Newline();
227 dpurdie 570
    $io->SetTag( "${name}_shld" );              # command tag
571
    $io->SetTerm( "\n" );
572
 
573
    $io->Label( "Linker commands", $name );     # label
574
 
575
                                                # object list
576
    $io->ObjList( $name, $pObjs, \&ToolsetObjRecipe );
577
 
578
    ToolsetLibStd( $pLibs );                    # push standard libraries
579
 
580
    $io->Cmd( "-Wl,$def_pref$def" ) if ($def);
581
 
582
    $io->Cmd( "-Wl,--start-group" ) if ($multi_scan);
583
    $io->LibList( $name, $pLibs, \&ToolsetLibRecipe );
584
    $io->Cmd( "-Wl,--end-group" ) if ($multi_scan);
585
 
586
    $io->Newline();
587
 
335 dpurdie 588
    #.. Dependency link,
589
    #   Create a library dependency file
590
    #       Create command file to build applicaton dependency list
591
    #       from the list of dependent libraries
592
    #
593
    #       Create makefile directives to include the dependency
594
    #       list into the makefile.
595
    #
596
    $io->DepRules( $pLibs, \&ToolsetLibRecipe, "\$(LIBDIR)/${shared}" );
339 dpurdie 597
    $io->SHLDDEPEND($name, $soname);
227 dpurdie 598
}
599
 
600
 
601
###############################################################################
271 dpurdie 602
# Function        : ToolsetLD
227 dpurdie 603
#
271 dpurdie 604
# Description     : Takes the user options and builds the rules required to
605
#                   link the program 'name'.
227 dpurdie 606
#
271 dpurdie 607
# Inputs          : $name           - base name of the program
608
#                   $pArgs          - Ref to program arguments
609
#                   $pObjs          - Ref to program objects
610
#                   $pLibs          - Ref to program library list
227 dpurdie 611
#
271 dpurdie 612
# Returns         : Nothing
227 dpurdie 613
#
271 dpurdie 614
# Output:         : Rules and recipes to create a program
615
#                       Create program rules and recipes
616
#                       Create linker input script
617
#                       Create library dependency list
618
#                       Include library dependency information
227 dpurdie 619
#
620
sub ToolsetLD
621
{
622
    my( $name, $pArgs, $pObjs, $pLibs ) = @_;
623
    my $static = $::ScmCompilerOpts{'STATIC_PROGS'};
624
    my $multi_scan;
625
 
626
#.. Parse arguments
627
#
628
    foreach $_ ( @$pArgs )
629
    {
630
        if ( m/^--Static$/ ) {
631
            $static = 1;
632
 
633
        } elsif ( m/^--Shared/ ) {
634
            $static = 0;
635
 
636
        } elsif ( /^--MultiScan/i ) {
637
            $multi_scan = 1;
638
 
639
        } elsif ( /^--NoMultiScan/i ) {
640
            $multi_scan = 0;
641
 
642
        } else {
643
            Message( "LD: unknown option $_ -- ignored\n" );
644
        }
645
    }
646
 
271 dpurdie 647
#.. Names of programs and components
648
#
649
    my $base = "\$(BINDIR)/${name}";
650
    my $full = $base . $::exe;
651
    my $map  = $base . '.map';
652
    my $ld  =  $base . '.ld';
653
 
227 dpurdie 654
#.. Cleanup rules
655
#
271 dpurdie 656
    ToolsetGenerate( $ld );
657
    ToolsetGenerate( $map );
227 dpurdie 658
 
659
#.. Build rules
660
#
661
    my ($io) = ToolsetPrinter::New();
335 dpurdie 662
    my $dep = $io->SetLdTarget( $name );
227 dpurdie 663
 
271 dpurdie 664
    $io->Prt( "$full : $dep " );
665
    $io->Entry( "", "", "\\\n\t", ".$::o ", @$pObjs );
666
    $io->Prt( "\n\t\$(LD)\n\n" );
227 dpurdie 667
 
271 dpurdie 668
 
227 dpurdie 669
#.. Linker command file
670
#
671
#       Now the fun part... piecing together a variable $(name_ld)
672
#       which ends up in the command file.
673
#
674
    $io->SetTag( "${name}_ld" );                # macro tag
675
    $io->SetTerm( "\n" );
676
 
677
    $io->Label( "Linker commands", $name );     # label
678
 
679
    $io->Cmd( "-static" ) if ($static);         # Link as a static program
680
 
681
                                                # object list
682
    $io->ObjList( $name, $pObjs, \&ToolsetObjRecipe );
683
 
684
    ToolsetLibStd( $pLibs );                    # push standard libraries
685
 
686
                                                # library list
687
    $io->Cmd( "-Wl,--start-group" ) if ($multi_scan);
688
    $io->LibList( $name, $pLibs, \&ToolsetLibRecipe );
689
    $io->Cmd( "-Wl,--end-group" ) if ($multi_scan);
690
 
691
    $io->Newline();
692
 
335 dpurdie 693
    #.. Dependency link,
694
    #   Create a library dependency file
695
    #       Create command file to build applicaton dependency list
696
    #       from the list of dependent libraries
697
    #
698
    #       Create makefile directives to include the dependency
699
    #       list into the makefile.
700
    #
701
    $io->DepRules( $pLibs, \&ToolsetLibRecipe, $base );
702
    $io->LDDEPEND();
271 dpurdie 703
 
704
#.. Package up the program and other artifacts
705
#
706
    PackageProgAddFiles ( $name, $full );
707
 
227 dpurdie 708
}
709
 
710
 
711
########################################################################
712
#
713
#   Push standard "system" libraries. This is a helper function
714
#   used within this toolset.
715
#
716
#   Arguments:
717
#       $plib       Reference to library array.
718
#
719
########################################################################
720
 
721
sub ToolsetLibStd
722
{
723
}
724
 
725
 
726
########################################################################
727
#
728
#   Generate a linker object recipe.  This is a helper function used 
729
#   within this toolset.
730
#
731
#   Arguments:
732
#       $io         I/O stream
733
#
734
#       $target     Name of the target
735
#
736
#       $obj        Library specification
737
#
738
########################################################################
739
 
740
sub ToolsetObjRecipe
741
{
742
    my ($io, $target, $obj) = @_;
743
 
744
    $io->Cmd( "\$(strip $obj).$::o" );
745
}
746
 
747
 
748
###############################################################################
749
#
750
#   Parse a linker lib list
751
#   This is a helper function used within this toolset
752
#
753
#   Arguments:
754
#       $target     Name of the target
755
#
756
#       $lib        Library specification
757
#
758
#       $tag        Tag (user specified)
759
#
760
#       $dp         If building a depend list, the full target name.
761
#
762
###############################################################################
763
 
764
sub ToolsetLibRecipe
765
{
766
    my ($io, $target, $lib, $dp) = @_;
767
 
768
    if ( ! defined($dp) ) {                     # linker
769
        $lib =~ s/^lib//;                       # .. remove leading 'lib'
770
        $io->Cmd( "-l$lib" );
771
 
772
    } else {                                    # depend
773
        $io->Cmd( "$dp:\t@(vlib2,$lib,GCC_LIB)" );
774
 
775
    }
776
}
777
 
778
#.. Successful termination
779
1;
780