Subversion Repositories DevTools

Rev

Rev 373 | Rev 3965 | Go to most recent revision | Details | Compare with Previous | 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
{
373 dpurdie 104
    my( $GCCTarget, $GCCToolchain, $GCCRoot, $GCCBin, $GCCAr, $GCCFlags, $GCCObjCopy );
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';
373 dpurdie 205
        $GCCObjCopy =  '${GCC_ROOT}/' . $GCCToolchain->{BASE} . 'objcopy';
369 dpurdie 206
        $GCCFlags = $GCCToolchain->{CC_OPTS};
227 dpurdie 207
    }
208
    else
209
    {
373 dpurdie 210
        $GCCRoot = '/usr';
211
        $GCCBin = 'gcc';
212
        $GCCAr = 'ar';
213
        $GCCObjCopy =  'objcopy';
227 dpurdie 214
    }
215
 
216
#.. Define GCC environment
217
#
218
    PlatformDefine( "
219
#################################################
220
# GCC toolchain definitions 
221
#
222
#..");
369 dpurdie 223
    PlatformDefine( "GCC_TARGET         := $GCCTarget" );
224
    PlatformDefine( "GCC_ROOT           := $GCCRoot" );
225
    PlatformDefine( "GCC_CC             := $GCCBin" );
226
    PlatformDefine( "GCC_AR             := $GCCAr" );
373 dpurdie 227
    PlatformDefine( "GCC_OBJCOPY        := $GCCObjCopy" );
227 dpurdie 228
    PlatformDefine( "" );
229
 
369 dpurdie 230
    PlatformDefine( "GCC_CFLAGS         := $GCCFlags" ) if defined $GCCFlags;
231
 
232
 
227 dpurdie 233
    #
234
    #   Required since this toolset advertises: ScmToolsetCompilerPath
235
    #
369 dpurdie 236
    PlatformDefine( "SCM_COMPILERPATH   := \$\{GCC_CC\}" );
237
    PlatformDefine( "" );
227 dpurdie 238
 
239
 
240
#.. Piece the world together
241
#
242
    Init( "gcc" );
243
    ToolsetDefines( "gcc.def" );
244
    ToolsetRules( "gcc.rul" );
245
    ToolsetRules( "standard.rul" );
246
 
247
#   Create a standard data structure
248
#   This is a hash of hashes
249
#       The first hash is keyed by CompileOption keyword
250
#       The second hash contains pairs of values to set or remove
251
#
252
    %::ScmToolsetCompilerOptions =
253
    (
254
        #
255
        #   Control the thread model to use
256
        #   This will affect the compiler options and the linker options
257
        #
258
        'staticprogs'        => { 'STATIC_PROGS' , '1' },      # Progams link staticlly
259
        'no_staticprogs'     => { 'STATIC_PROGS' , undef },    # Default
260
    );
261
 
262
    #
263
    #   Set default options
264
    #
265
    $::ScmCompilerOpts{'STATIC_PROGS'} = undef;
266
}
267
 
268
 
269
###############################################################################
270
#   ToolsetCC( $source, $obj, \@args )
271
#       This subroutine takes the user options and builds the rule(s)
272
#       required to compile the source file 'source' to 'obj'
273
#
274
###############################################################################
275
 
276
sub ToolsetCC
277
{
278
    my( $source, $obj, $pArgs ) = @_;
279
    my( $cflags, $file ) = "";
280
 
281
    foreach $_ ( @$pArgs ) {
282
        if (/--Shared$/) {                      # Building a 'shared' object
283
            $cflags  = "$cflags \$(SHCFLAGS)";
284
        } else {
285
            Message( "CC: unknown option $_ -- ignored\n" );
286
        }
287
    }
288
 
289
    MakePrint( "\n\t\$(CC)\n" );
290
    if ( $cflags )
291
    {                                           # object specific CFLAGS
292
        MakePadded( 4, "\$(OBJDIR)/$obj.$::o:" );
293
        MakePrint( "\tCFLAGS +=$cflags\n" );
294
    }
295
 
296
    $file = StripExt( $obj );                   # Metric working file
297
    ToolsetGenerate( "\$(OBJDIR)/$file.met" );
298
}
299
 
300
 
301
###############################################################################
302
#   ToolsetCCDepend( $depend, \@sources )
303
#       This subroutine takes the user options and builds the
304
#       rule(s) required to build the dependencies for the source
305
#       files 'sources' to 'depend'.
306
#
307
###############################################################################
308
 
309
sub ToolsetCCDepend
310
{
311
    MakePrint( "\t\$(CCDEPEND)\n" );
312
}
313
 
314
 
315
###############################################################################
316
#   ToolsetCXX( $source, $obj, \@args )
317
#       This subroutine takes the user options and builds the rule(s)
318
#       required to compile the source file 'source' to 'obj'
319
#
320
###############################################################################
321
 
322
sub ToolsetCXX
323
{
324
    my( $source, $obj, $pArgs ) = @_;
325
    my( $cflags, $file ) = "";
326
 
327
    foreach $_ ( @$pArgs ) {
328
        if (/--Shared$/) {                      # Building a 'shared' object
329
            $cflags  = "$cflags \$(SHCXXFLAGS)";
330
        } else {
331
            Message( "CXX: unknown option $_ -- ignored\n" );
332
        }
333
    }
334
 
335
    MakePrint( "\n\t\$(CXX)\n" );
336
    if ( $cflags )
337
    {                                           # object specific CFLAGS
338
        MakePadded( 4, "\$(OBJDIR)/$obj.$::o:" );
339
        MakePrint( "\tCXXFLAGS +=$cflags\n" );
340
    }
341
 
342
    $file = StripExt( $obj );                   # Metric working file
343
    ToolsetGenerate( "\$(OBJDIR)/$file.met" );
344
}
345
 
346
 
347
###############################################################################
348
#   ToolsetCXXDepend( $depend, \@sources )
349
#       This subroutine takes the user options and builds the
350
#       rule(s) required to build the dependencies for the source
351
#       files 'sources' to 'depend'.
352
#
353
###############################################################################
354
 
355
sub ToolsetCXXDepend
356
{
287 dpurdie 357
    ToolsetCCDepend();
227 dpurdie 358
}
359
 
360
 
361
###############################################################################
362
#   ToolsetAS( $source, $obj, \@args )
363
#       This subroutine takes the user options and builds the rule(s)
364
#       required to compile the source file 'source' to 'obj'
365
#
366
###############################################################################
367
 
368
sub ToolsetAS
369
{
370
    MakePrint( "\n\t\$(AS)\n" );
371
}
372
 
373
sub ToolsetASDepend
374
{
375
}
376
 
377
 
378
###############################################################################
379
#   ToolsetAR( $name, \@args, \@objs )
380
#       This subroutine takes the user options and builds the rules
381
#       required to build the library 'name'.
382
#
383
#   Arguments:
384
#       n/a
385
#
386
#   Output:
387
#       $(BINDIR)/name$.${a}:   .... ]
388
#           $(AR)
389
#
390
#       name_ld += ...  Linker command file
391
#           :
392
#
393
#       name_dp += ...  Dependency list
394
#           :
395
#
396
###############################################################################
397
 
398
sub ToolsetAR
399
{
400
    my( $name, $pArgs, $pObjs ) = @_;
401
 
402
#.. Parse arguments
403
#
404
    foreach $_ ( @$pArgs )
405
    {
406
        Message( "AR: unknown option $_ -- ignored\n" );
407
    }
408
 
409
#.. Target
410
#
411
    MakePrint( "#.. Library ($name)\n\n" );     # label
412
 
413
    MakeEntry( "\$(LIBDIR)/$name\$(GBE_TYPE).$::a:\t",
414
        "", "\\\n\t\t", ".$::o", @$pObjs );
415
 
416
#.. Build library rule (just append to standard rule)
417
#
418
    MakePrint( "\n\t\$(AR)\n\n" );
419
}
420
 
421
 
422
###############################################################################
423
#   ToolsetARMerge( $name, \@args, \@libs )
424
#       This subroutine takes the user options and builds the rules
425
#       required to build the library 'name' by merging the specified
426
#       libaries
427
#
428
#   Arguments:
429
#       --xxx                   No arguments currently defined
430
#
431
#   Output:
432
#       [ $(LIBDIR)/name$.${a}:   .... ]
433
#           ...
434
#
435
###############################################################################
436
 
437
sub ToolsetARMerge
438
{
439
    MakePrint( "\n\t\$(ARMERGE)\n\n" );
440
}
441
 
442
 
443
###############################################################################
289 dpurdie 444
#   ToolsetSHLD( $name, \@args, \@objs, \@libraries, $ver )
227 dpurdie 445
#       This subroutine takes the user options and builds the rules
339 dpurdie 446
#       required to link the Shared Library 'name'.
227 dpurdie 447
#
448
#   Arguments:
449
#   n/a
450
#
451
#   Output:
452
#       $(LIBDIR)/name:     $(LIBDIR)/shared
453
#           ln -s $shared $name
454
#
455
#       $(LIBDIR)/name.dep: $(GBE_OBJDIR)
456
#       $(LIBDIR)/name.dep: $(GBE_LIBDIR)
457
#       $(LIBDIR)/name.dep: $(GBE_PLATFORM).mk
458
#           $(SHLDDEPEND)
459
#
460
#       $(LIBDIR)/shared:   SHNAME=name
461
#       $(LIBDIR)/shared:   SHBASE=base
462
#       $(LIBDIR)/shared:   $(LIBDIR)/name.dep  \
463
#           $(OBJECTS)
464
#                           
465
#       ifneq "$(findstring $(IFLAG),23)" ""
466
#       -include            "$(LIBDIR)/name.dep"
467
#       endif
468
#
469
#       name_ld += ...
470
#           :
471
#
472
###############################################################################
473
 
474
sub ToolsetSHLD
475
{
289 dpurdie 476
    my( $name, $pArgs, $pObjs, $pLibs, $ver ) = @_;
373 dpurdie 477
    my( $linkname, $soname, $shared, $dbgname, $def, $def_pref, $multi_scan );
339 dpurdie 478
    my $sosuffix = '.' . $ver;
227 dpurdie 479
 
480
#.. Parse arguments
481
#
482
    foreach $_ ( @$pArgs )
483
    {
484
        if (/^--Def=(.*?)(\,(.*))?$/) {         # Library definition
485
            #
486
            #   Locate the Def file.
487
            #   If it is a generate file so it will be in the SRCS hash
488
            #   Otherwise the user will have to use Src to locate the file
489
            #
490
            $def = MakeSrcResolve($1);
491
            $def_pref = '';
492
            if ( $1 =~ m~\.def$~ ) {
493
                $def_pref = '--version-script='; # Old def file
494
            }
495
        } elsif ( /^--MultiScan/i ) {
496
            $multi_scan = 1;
497
 
498
        } elsif ( /^--NoMultiScan/i ) {
499
            $multi_scan = 0;
500
 
339 dpurdie 501
        } elsif ( /^--SoNameSuffix=(.*)/i ) {
502
            $sosuffix = $1;
503
 
227 dpurdie 504
        } else {
505
            Message( "SHLD: unknown option $_ -- ignored\n" );
506
        }
507
    }
508
 
339 dpurdie 509
#.. Various library names
227 dpurdie 510
#
339 dpurdie 511
    $linkname = "$name\$(GBE_TYPE).$::so";
512
    $shared = "$linkname.$ver";
513
    $soname = "$linkname$sosuffix";
373 dpurdie 514
 
515
    my $shared_path = "\$(LIBDIR)/${shared}";
516
    my $dbg_path =  $shared_path . '.dbg';
227 dpurdie 517
 
518
#.. Cleanup rules
519
#
520
#   map     Map file
521
#   ln      Link from LIBDIR to BINDIR
522
#
261 dpurdie 523
    ToolsetGenerate( "\$(LIBDIR)/${name}.map" );
524
    ToolsetGenerate( "\$(LIBDIR)/${shared}" );
339 dpurdie 525
    ToolsetGenerate( "\$(BINDIR)/${soname}" );
373 dpurdie 526
    ToolsetGenerate( $dbg_path );
227 dpurdie 527
 
528
#.. Build rules
529
#
530
#   name        Base name
531
#   shared      Library name, includes GBE_TYPE specification
532
#
533
    my ($io) = ToolsetPrinter::New();
335 dpurdie 534
    my $dep = $io->SetShldTarget($shared);
227 dpurdie 535
 
536
    $io->Label( "Shared library", $name );
339 dpurdie 537
    PackageShlibAddFiles( $name, "\$(LIBDIR)/$shared" );
373 dpurdie 538
    PackageShlibAddFiles( $name, $dbg_path );
339 dpurdie 539
 
227 dpurdie 540
    $io->Prt( "\$(LIBDIR)/${shared}:\tSHBASE=${name}\n" );
339 dpurdie 541
    $io->Prt( "\$(LIBDIR)/${shared}:\tSHNAME=${soname}\n" );
542
    $io->Prt( "\$(LIBDIR)/${shared}: \\\n\t\t${dep}" );
321 dpurdie 543
    $io->Entry( "", "", " \\\n\t\t", ".$::o", @$pObjs );
227 dpurdie 544
    $io->Prt( "\\\n\t\t$def" ) if($def);
373 dpurdie 545
    $io->Prt( "\n\t\$(SHLD)" );
546
    $io->Prt( "\n\t\$(call LDSTRIP,$shared_path,$dbg_path)\n\n" );
321 dpurdie 547
 
339 dpurdie 548
#
549
#   Create soft links
550
#       'Real Name' to its 'Link Name'
551
#       'Real Name' to 'SoName' in the BINDIR (for testing I think)
552
#       'Real Name' to 'SoName' in the LIBDIR (if different)
553
#
554
    $io->Label( "Shared library Symbolic Links", $name );
555
    PackageShlibAddFiles( $name, "\$(LIBDIR)/$linkname" );
556
    $io->Prt( "\$(LIBDIR)/$linkname:\t\\\n" .
557
              "\t\t\$(GBE_BINDIR)\\\n" .
558
              "\t\t\$(LIBDIR)/${shared}\n" .
559
              "\t\$(AA_PRE)(rm -f \$@; ln -s ./$shared \$@)\n" .
560
              "\t\$(AA_PRE)(rm -f \$(BINDIR)/$soname; ln -s ../\$(LIBDIR)/$shared \$(BINDIR)/$soname)\n\n" );
561
 
562
    if ( $soname ne $shared && $soname ne $linkname)
563
    {
564
        $io->Label( "Shared library SoName Symbolic Links", $name );
565
        PackageShlibAddFiles( $name, "\$(LIBDIR)/$soname" );
566
        $io->Prt( "\$(LIBDIR)/$soname:\t\\\n" .
567
                  "\t\t\$(GBE_LIBDIR)\\\n" .
568
                  "\t\t\$(LIBDIR)/${shared}\n" .
569
                  "\t\$(AA_PRE)(rm -f \$@; ln -s ./$shared \$@)\n" );
570
    }
571
 
227 dpurdie 572
#.. Linker command file
573
#
574
#       Now the fun part... piecing together a variable $(name_shld)
575
#       which ends up in the command file.
576
#
339 dpurdie 577
    $io->Newline();
227 dpurdie 578
    $io->SetTag( "${name}_shld" );              # command tag
579
    $io->SetTerm( "\n" );
580
 
581
    $io->Label( "Linker commands", $name );     # label
582
 
583
                                                # object list
584
    $io->ObjList( $name, $pObjs, \&ToolsetObjRecipe );
585
 
586
    ToolsetLibStd( $pLibs );                    # push standard libraries
587
 
588
    $io->Cmd( "-Wl,$def_pref$def" ) if ($def);
589
 
590
    $io->Cmd( "-Wl,--start-group" ) if ($multi_scan);
591
    $io->LibList( $name, $pLibs, \&ToolsetLibRecipe );
592
    $io->Cmd( "-Wl,--end-group" ) if ($multi_scan);
593
 
594
    $io->Newline();
595
 
335 dpurdie 596
    #.. Dependency link,
597
    #   Create a library dependency file
598
    #       Create command file to build applicaton dependency list
599
    #       from the list of dependent libraries
600
    #
601
    #       Create makefile directives to include the dependency
602
    #       list into the makefile.
603
    #
604
    $io->DepRules( $pLibs, \&ToolsetLibRecipe, "\$(LIBDIR)/${shared}" );
339 dpurdie 605
    $io->SHLDDEPEND($name, $soname);
227 dpurdie 606
}
607
 
608
 
609
###############################################################################
271 dpurdie 610
# Function        : ToolsetLD
227 dpurdie 611
#
271 dpurdie 612
# Description     : Takes the user options and builds the rules required to
613
#                   link the program 'name'.
227 dpurdie 614
#
271 dpurdie 615
# Inputs          : $name           - base name of the program
616
#                   $pArgs          - Ref to program arguments
617
#                   $pObjs          - Ref to program objects
618
#                   $pLibs          - Ref to program library list
227 dpurdie 619
#
271 dpurdie 620
# Returns         : Nothing
227 dpurdie 621
#
271 dpurdie 622
# Output:         : Rules and recipes to create a program
623
#                       Create program rules and recipes
624
#                       Create linker input script
625
#                       Create library dependency list
626
#                       Include library dependency information
227 dpurdie 627
#
628
sub ToolsetLD
629
{
630
    my( $name, $pArgs, $pObjs, $pLibs ) = @_;
631
    my $static = $::ScmCompilerOpts{'STATIC_PROGS'};
632
    my $multi_scan;
633
 
634
#.. Parse arguments
635
#
636
    foreach $_ ( @$pArgs )
637
    {
638
        if ( m/^--Static$/ ) {
639
            $static = 1;
640
 
641
        } elsif ( m/^--Shared/ ) {
642
            $static = 0;
643
 
644
        } elsif ( /^--MultiScan/i ) {
645
            $multi_scan = 1;
646
 
647
        } elsif ( /^--NoMultiScan/i ) {
648
            $multi_scan = 0;
649
 
650
        } else {
651
            Message( "LD: unknown option $_ -- ignored\n" );
652
        }
653
    }
654
 
271 dpurdie 655
#.. Names of programs and components
656
#
657
    my $base = "\$(BINDIR)/${name}";
658
    my $full = $base . $::exe;
659
    my $map  = $base . '.map';
660
    my $ld  =  $base . '.ld';
373 dpurdie 661
    my $dbg =  $base . '.dbg';
271 dpurdie 662
 
227 dpurdie 663
#.. Cleanup rules
664
#
271 dpurdie 665
    ToolsetGenerate( $ld );
666
    ToolsetGenerate( $map );
373 dpurdie 667
    ToolsetGenerate( $dbg );
227 dpurdie 668
 
669
#.. Build rules
670
#
671
    my ($io) = ToolsetPrinter::New();
335 dpurdie 672
    my $dep = $io->SetLdTarget( $name );
227 dpurdie 673
 
271 dpurdie 674
    $io->Prt( "$full : $dep " );
675
    $io->Entry( "", "", "\\\n\t", ".$::o ", @$pObjs );
373 dpurdie 676
    $io->Prt( "\n\t\$(LD)" );
677
    $io->Prt( "\n\t\$(call LDSTRIP,$full,$dbg)\n\n" );
227 dpurdie 678
 
271 dpurdie 679
 
227 dpurdie 680
#.. Linker command file
681
#
682
#       Now the fun part... piecing together a variable $(name_ld)
683
#       which ends up in the command file.
684
#
685
    $io->SetTag( "${name}_ld" );                # macro tag
686
    $io->SetTerm( "\n" );
687
 
688
    $io->Label( "Linker commands", $name );     # label
689
 
690
    $io->Cmd( "-static" ) if ($static);         # Link as a static program
691
 
692
                                                # object list
693
    $io->ObjList( $name, $pObjs, \&ToolsetObjRecipe );
694
 
695
    ToolsetLibStd( $pLibs );                    # push standard libraries
696
 
697
                                                # library list
698
    $io->Cmd( "-Wl,--start-group" ) if ($multi_scan);
699
    $io->LibList( $name, $pLibs, \&ToolsetLibRecipe );
700
    $io->Cmd( "-Wl,--end-group" ) if ($multi_scan);
701
 
702
    $io->Newline();
703
 
335 dpurdie 704
    #.. Dependency link,
705
    #   Create a library dependency file
706
    #       Create command file to build applicaton dependency list
707
    #       from the list of dependent libraries
708
    #
709
    #       Create makefile directives to include the dependency
710
    #       list into the makefile.
711
    #
712
    $io->DepRules( $pLibs, \&ToolsetLibRecipe, $base );
713
    $io->LDDEPEND();
271 dpurdie 714
 
715
#.. Package up the program and other artifacts
716
#
717
    PackageProgAddFiles ( $name, $full );
373 dpurdie 718
    PackageProgAddFiles ( $name, $dbg );
271 dpurdie 719
 
227 dpurdie 720
}
721
 
722
 
723
########################################################################
724
#
725
#   Push standard "system" libraries. This is a helper function
726
#   used within this toolset.
727
#
728
#   Arguments:
729
#       $plib       Reference to library array.
730
#
731
########################################################################
732
 
733
sub ToolsetLibStd
734
{
735
}
736
 
737
 
738
########################################################################
739
#
740
#   Generate a linker object recipe.  This is a helper function used 
741
#   within this toolset.
742
#
743
#   Arguments:
744
#       $io         I/O stream
745
#
746
#       $target     Name of the target
747
#
748
#       $obj        Library specification
749
#
750
########################################################################
751
 
752
sub ToolsetObjRecipe
753
{
754
    my ($io, $target, $obj) = @_;
755
 
756
    $io->Cmd( "\$(strip $obj).$::o" );
757
}
758
 
759
 
760
###############################################################################
761
#
762
#   Parse a linker lib list
763
#   This is a helper function used within this toolset
764
#
765
#   Arguments:
766
#       $target     Name of the target
767
#
768
#       $lib        Library specification
769
#
770
#       $tag        Tag (user specified)
771
#
772
#       $dp         If building a depend list, the full target name.
773
#
774
###############################################################################
775
 
776
sub ToolsetLibRecipe
777
{
778
    my ($io, $target, $lib, $dp) = @_;
779
 
780
    if ( ! defined($dp) ) {                     # linker
781
        $lib =~ s/^lib//;                       # .. remove leading 'lib'
782
        $io->Cmd( "-l$lib" );
783
 
784
    } else {                                    # depend
785
        $io->Cmd( "$dp:\t@(vlib2,$lib,GCC_LIB)" );
786
 
787
    }
788
}
789
 
790
#.. Successful termination
791
1;
792