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
 
4034 dpurdie 16
our $ScmPlatform;
17
our $ScmNoToolsTest;
18
 
227 dpurdie 19
##############################################################################
20
#   Configuration information
21
#   Cross reference from CrossCompiler Alias to actual paths
22
#   Structure:
23
#   Hash reference: Array of toolchain information
369 dpurdie 24
#       Mandatory
25
#          ROOT             => Root of compiler
26
#          BASE             => Base for binaries
27
#       Optional
28
#          CC_OPTS          => Additonal Compiler options
4034 dpurdie 29
#          CC_OPTSP         => Production Compiler options
30
#          CC_OPTSD         => Debug Compiler options
369 dpurdie 31
#          UNCONTROLLED     => Boolean to create warning
3967 dpurdie 32
#          PACKAGE_ARCH     => Packageing architecture
33
#          VERSION          => Version reported by GCC
34
#          MACHINE          => Machine reported by GCC
4034 dpurdie 35
#          COMPILER_OPTIONS => Toolset specific compiler initial options
36
#                              This is a comma seperated list
369 dpurdie 37
 
227 dpurdie 38
my %ToolsetConfig = (
39
 
369 dpurdie 40
    'i386-unknown-linux-gnu'    => {
41
        ROOT => '/opt/crosstool/gcc-4.1.1-glibc-2.5/i586-unknown-linux-gnu',
42
        BASE => 'bin/i586-unknown-linux-gnu-',
3967 dpurdie 43
       VERSION      => '4.1.1',
44
       MACHINE      => 'i586-unknown-linux-gnu'
369 dpurdie 45
    },
227 dpurdie 46
 
369 dpurdie 47
    'arm-9tdmi-linux-gnu'       => {
48
        ROOT => '/opt/crosstool/gcc-4.1.1-glibc-2.5/arm-9tdmi-linux-gnu',
3967 dpurdie 49
        BASE => 'bin/arm-9tdmi-linux-gnu-',
50
        VERSION      => '4.1.1',
51
        MACHINE      => 'arm-9tdmi-linux-gnu'
369 dpurdie 52
        },
247 dpurdie 53
 
369 dpurdie 54
    'powerpc-603e-linux-gnu'    => {
55
       ROOT => '/opt/crosstool/gcc-4.1.1-glibc-2.5/powerpc-603e-linux-gnu',
3967 dpurdie 56
       BASE => 'bin/powerpc-603e-linux-gnu-',
57
       VERSION      => '4.1.1',
58
       MACHINE      => 'powerpc-603e-linux-gnu'
369 dpurdie 59
    },
337 dpurdie 60
 
369 dpurdie 61
    'arm-926ejs-linux-gnueabi'  => {
62
       ROOT => '/opt/crosstool/gcc-4.4.3-glibc-2.9/arm-926ejs-linux-gnueabi',
63
       BASE => 'bin/arm-926ejs-linux-gnueabi-',
64
       CC_OPTS => '-Wno-psabi',
3967 dpurdie 65
       VERSION      => '4.4.3',
66
       MACHINE      => 'arm-926ejs-linux-gnueabi'
369 dpurdie 67
    },
68
 
3967 dpurdie 69
    'i686-linux-gnu'    => {
70
       ROOT         => '/usr',
71
       BASE         => 'bin/',
72
       PACKAGE_ARCH => 'i386',
73
       VERSION      => '4.6',
74
       MACHINE      => 'i686-linux-gnu'
75
    },
76
 
4109 dpurdie 77
    'arm-iwmmxt-linux-gnueabi'  => {
78
       ROOT => '/opt/marvel',
79
       BASE => 'bin/arm-iwmmxt-linux-gnueabi-',
80
       VERSION      => '4.2.4',
81
       MACHINE      => 'arm-iwmmxt-linux-gnueabi'
82
    },
83
 
84
 
227 dpurdie 85
    #
86
    #   Old (not to be used) version of the embedded toolchain
4003 dpurdie 87
    #   This was deprecated in favor of gcc-4.1.1-glibc-2.5
227 dpurdie 88
    #   It is not possible to reproduce old packages using the old compiler
89
    #   This is a known issue
90
    #
369 dpurdie 91
    'i386-unknown-linux-gnu.glibc-2.3.2' => {
92
       ROOT => '/opt/crosstool/gcc-4.1.0-glibc-2.3.2/i386-unknown-linux-gnu',
93
       BASE => 'bin/i386-unknown-linux-gnu-'
94
    },
227 dpurdie 95
 
369 dpurdie 96
    'arm-9tdmi-linux-gnu.glibc-2.3.2' => {
97
       ROOT => '/opt/crosstool/gcc-4.1.0-glibc-2.3.2/arm-9tdmi-linux-gnu',
98
       BASE => 'bin/arm-9tdmi-linux-gnu-'
99
    },
227 dpurdie 100
 
101
    #
102
    #   Not too sure where this is used
103
    #
369 dpurdie 104
    'armv4l-unknown-linux-gcc' => {
105
       ROOT => '/opt/host/armv4l',
106
       BASE => 'bin/armv4l-unknown-linux-'
107
    },
227 dpurdie 108
 
109
    #
110
    #   The compiler for the current local machine
111
    #
369 dpurdie 112
    'i386-unknown-linux-gcc' => {
113
       ROOT => '/usr',
114
       BASE => 'bin/',
115
       UNCONTROLLED => 1,
3967 dpurdie 116
       PACKAGE_ARCH => 'i386',
369 dpurdie 117
    },
118
);
227 dpurdie 119
 
120
#
121
#   Cross reference from GCCTarget to GBE_MACHTYPE for which it can
122
#   build using the 'native gcc'. This is NOT the preferred mode of operation
123
#   as the compiler is not as controlled as the cross compilers.
124
#
125
my %NativeCompilers = (
126
    'Linux i386'       => 'linux_i386',
127
    );
128
 
129
##############################################################################
130
#   ToolsetInit()
131
#       Runtime initialisation
132
#
133
##############################################################################
134
 
135
ToolsetInit();
136
 
137
sub ToolsetInit
138
{
4034 dpurdie 139
    my( $GCCTarget, $GCCToolchain, $GCCRoot, $GCCBin, $GCCAr, $GCCObjCopy );
140
    my( $GCCFlags,  $GCCFlagsP, $GCCFlagsD );
3967 dpurdie 141
    my( $PkgArch);
4034 dpurdie 142
    my( $arg_alias, $tools_found, $compiler_tool );
227 dpurdie 143
 
144
#.. Toolset configuration
145
#
146
    $::ScmToolsetVersion = "1.0.0";             # our version
147
    $::ScmToolsetGenerate = 0;                  # GEN generate optional
148
    $::ScmToolsetCompilerPath = 1;              # Exports Compiler path to makefile via SCM_COMPILERPATH
271 dpurdie 149
    $::ScmToolsetProgDependancies = 0;          # handle Prog dependancies myself
339 dpurdie 150
    $::ScmToolsetSoName = 1;                    # Shared library supports SoName
227 dpurdie 151
 
152
#.. Standard.rul requirements
153
#
154
    $::s = "asm";
155
    $::o = "o";
156
    $::so = "so";
157
    $::a = "a";
158
    $::exe = "";
159
 
160
#.. Parse arguments
161
#
162
    foreach $_ ( @::ScmToolsetArgs ) {
163
        if (/^--Target=(.*)/) {                 # OS Version
164
            $GCCTarget = "$1";
165
 
166
        } elsif (/^--CrossAlias=(.*)/) {        # CrossCompiler target-alias
167
            $arg_alias = $1;
168
 
4034 dpurdie 169
        } elsif (/^--CompilerTool=(.*)/) {      # CrossCompiler located in package
170
            $compiler_tool = $1;
171
 
227 dpurdie 172
        } else {
173
            Message( "gcc toolset: unknown option $_ -- ignored\n" );
174
        }
175
    }
176
 
177
    foreach $_ ( @::ScmPlatformArgs ) {
178
        if (/^--product=(.*)/) {                # GBE product
179
 
180
        } else {
181
            Message( "gcc toolset: unknown platform argument $_ -- ignored\n" );
182
        }
183
    }
184
 
185
    Error ("TOOLSET/gcc - Target undefined" )
186
        unless ($GCCTarget);
187
 
4034 dpurdie 188
    #
189
    #   If the toolset is not required, then do not process any futher
190
    #   We may not find the compiler
191
    #
192
    return
193
        if ($ScmNoToolsTest);
194
 
227 dpurdie 195
#.. Cross compile support
4034 dpurdie 196
#   Compiler provided in package, rather than install on machine
227 dpurdie 197
#
4034 dpurdie 198
if ( $compiler_tool  )
199
{
200
    #
201
    #   The GCC toolset will handle a compiler provided within a package
202
    #   Initial requirement was for ANDROID NDKs where the compiler is
203
    #   a part of the NDK and will change.
204
    #
205
    #   Compilers in packages will have a file in gbe/COMPILERS/<compiler_tool>
206
    #   that contains data specifically designed for this toolset
207
    #
208
    Verbose("Locate compiler in package: $compiler_tool");
209
    my @toolList;
210
    my $toolPath;
211
    my $toolPkg;
212
    for my $entry (@{$::ScmBuildPkgRules{$ScmPlatform} })
213
    {
214
        my $tpath = join('/', $entry->{ROOT}, 'gbe', 'COMPILERS' , $compiler_tool);
215
        if ( -f $tpath  )
216
        {
217
            push @toolList, $entry->{NAME};
218
            $toolPath = $tpath;
219
            $toolPkg = $entry;
220
        }
221
    }
222
    Error ("Multiple packages provide required compiler:", @toolList)
223
        if ( scalar(@toolList) > 1 );
224
    Error ("Required compiler not found in any package", "Compiler: $compiler_tool")
225
        unless ( scalar(@toolList) == 1 );
226
 
227
    #
228
    #   Process the compiler info file
229
    #   Rip out the data and create a hash of item/values
230
    #   File format:
231
    #       '#' is a line comment
232
    #       item=value
233
    #
234
    my %data;
235
    open (my $DATA, '<', $toolPath ) || Error("Cannot open compiler datafile. $!", "File: $toolPath");
236
    while ( <$DATA> )
237
    {
238
        $_ =~ s~\s+$~~;
239
        next if ( m~^#~ );
240
        m~(.*?)\s*=\s*(.*)~;
241
        $data{$1} = $2;
242
    }
243
    close $DATA;
244
 
245
    #
246
    #   Force this compilers data into the ToolsetConfig hash
247
    #
248
    $arg_alias = $compiler_tool;
249
    %ToolsetConfig = ();
250
 
251
    $ToolsetConfig{$arg_alias}{ROOT} = join('/', $toolPkg->{ROOT}, $data{ROOT} );
252
    $ToolsetConfig{$arg_alias}{BASE} = $data{BASE} . '-';
253
    $ToolsetConfig{$arg_alias}{CC_OPTS} = $data{CFLAGS};
254
    $ToolsetConfig{$arg_alias}{CC_OPTSP} = $data{CFLAGSP};
255
    $ToolsetConfig{$arg_alias}{CC_OPTSD} = $data{CFLAGSD};
256
    $ToolsetConfig{$arg_alias}{VERSION} = $data{VERSION};
257
    $ToolsetConfig{$arg_alias}{MACHINE} = $data{MACHINE};
258
    $ToolsetConfig{$arg_alias}{COMPILER_OPTIONS} = $data{COMPILER_OPTIONS};
259
}
260
 
261
#.. Cross compile support
262
#
227 dpurdie 263
#   Toolchain=root,[bin]
264
#
265
    if ( $arg_alias )
266
    {
267
        if ( exists $ToolsetConfig{ $arg_alias } )
268
        {
369 dpurdie 269
            $GCCToolchain = $ToolsetConfig{ $arg_alias };
270
            $tools_found = (-d $GCCToolchain->{ROOT});
227 dpurdie 271
            Warning ("gcc toolset: CrossPlatform toolchain not found for: $arg_alias",
369 dpurdie 272
                     "Path: $GCCToolchain->{ROOT}" ) unless $tools_found;
227 dpurdie 273
        }
274
        else
275
        {
276
            Error("gcc toolset: CrossPlatform Alias not configured: $arg_alias");
277
        }
369 dpurdie 278
 
279
        Warning ("Uncontrolled toolchain used: $arg_alias")
280
            if ( exists($GCCToolchain->{UNCONTROLLED}) && $GCCToolchain->{UNCONTROLLED} );
227 dpurdie 281
    }
282
 
283
    #
284
    #   If no Cross compiler toolchain is found (preferred method), then attempt
285
    #   to match a native compiler. Only known targets allow a native build
286
    #
287
    unless ( $tools_found )
288
    {
289
        if ( exists ( $NativeCompilers{$GCCTarget} ))
290
        {
291
            if ( $NativeCompilers{$GCCTarget} eq $::GBE_MACHTYPE )
292
            {
293
                $tools_found = 1;
369 dpurdie 294
                $GCCToolchain = undef;
227 dpurdie 295
            }
296
        }
297
    }
298
 
299
    #
300
    #   Must have a toolset by now, either a cross compiler or Native
301
    #
302
    Error ("gcc toolset: Toolchain not found for: $GCCTarget" )
303
        unless ( $tools_found );
304
 
305
 
369 dpurdie 306
    if ( defined $GCCToolchain )
227 dpurdie 307
    {
308
        #
369 dpurdie 309
        #   Parse GCCToolchain. Potential parts to create
310
        #       GCCRoot     - Location to find the effective /usr/include directory
311
        #       GCCBin      - Path to the gcc executable
312
        #       GCCAr       - Path to the ar executable
4034 dpurdie 313
        #       GCCFlags    - Additional compiler flags. Also Production and Debug
227 dpurdie 314
        #
369 dpurdie 315
        $GCCRoot = $GCCToolchain->{ROOT};
316
        $GCCBin = '${GCC_ROOT}/' . $GCCToolchain->{BASE} . 'gcc';
317
        $GCCAr =  '${GCC_ROOT}/' . $GCCToolchain->{BASE} . 'ar';
373 dpurdie 318
        $GCCObjCopy =  '${GCC_ROOT}/' . $GCCToolchain->{BASE} . 'objcopy';
369 dpurdie 319
        $GCCFlags = $GCCToolchain->{CC_OPTS};
4034 dpurdie 320
        $GCCFlagsP = $GCCToolchain->{CC_OPTSP};
321
        $GCCFlagsD = $GCCToolchain->{CC_OPTSD};
3967 dpurdie 322
        $PkgArch = $GCCToolchain->{PACKAGE_ARCH};
227 dpurdie 323
    }
324
    else
325
    {
373 dpurdie 326
        $GCCRoot = '/usr';
327
        $GCCBin = 'gcc';
328
        $GCCAr = 'ar';
329
        $GCCObjCopy =  'objcopy';
227 dpurdie 330
    }
331
 
332
#.. Define GCC environment
333
#
334
    PlatformDefine( "
335
#################################################
336
# GCC toolchain definitions 
337
#
338
#..");
369 dpurdie 339
    PlatformDefine( "GCC_TARGET         := $GCCTarget" );
340
    PlatformDefine( "GCC_ROOT           := $GCCRoot" );
341
    PlatformDefine( "GCC_CC             := $GCCBin" );
342
    PlatformDefine( "GCC_AR             := $GCCAr" );
373 dpurdie 343
    PlatformDefine( "GCC_OBJCOPY        := $GCCObjCopy" );
369 dpurdie 344
    PlatformDefine( "GCC_CFLAGS         := $GCCFlags" ) if defined $GCCFlags;
4034 dpurdie 345
    PlatformDefine( "GCC_CFLAGSP        := $GCCFlagsP" ) if defined $GCCFlagsP;
346
    PlatformDefine( "GCC_CFLAGSD        := $GCCFlagsD" ) if defined $GCCFlagsD;
369 dpurdie 347
 
227 dpurdie 348
    #
349
    #   Required since this toolset advertises: ScmToolsetCompilerPath
350
    #
369 dpurdie 351
    PlatformDefine( "SCM_COMPILERPATH   := \$\{GCC_CC\}" );
3967 dpurdie 352
 
353
    #
354
    #   Sanity checking
355
    #
356
    PlatformDefine( "GCC_EVERSION       := " . $GCCToolchain->{VERSION} ) if defined $GCCToolchain->{VERSION};
357
    PlatformDefine( "GCC_EMACHINE       := " . $GCCToolchain->{MACHINE} ) if defined $GCCToolchain->{MACHINE};
358
 
359
    #
360
    #   Option indication of packaging architecture
361
    #   Used by non-embedded systems for packaging. See debian_packager
362
    #
363
    PlatformDefine( "PACKAGE_ARCH       := $PkgArch" ) if (defined $PkgArch);
369 dpurdie 364
    PlatformDefine( "" );
227 dpurdie 365
 
366
#.. Piece the world together
367
#
3967 dpurdie 368
    Init( 'gcc' );
227 dpurdie 369
    ToolsetDefines( "gcc.def" );
370
    ToolsetRules( "gcc.rul" );
371
    ToolsetRules( "standard.rul" );
372
 
4094 dpurdie 373
 
374
    PlatformDefine( "CTAGS_EXE:= ctags" );
375
    ToolsetRequire( "exctags" );                # and Exuberant Ctags
376
 
227 dpurdie 377
#   Create a standard data structure
378
#   This is a hash of hashes
379
#       The first hash is keyed by CompileOption keyword
380
#       The second hash contains pairs of values to set or remove
381
#
382
    %::ScmToolsetCompilerOptions =
383
    (
384
        #
385
        #   Control the thread model to use
386
        #   This will affect the compiler options and the linker options
387
        #
388
        'staticprogs'        => { 'STATIC_PROGS' , '1' },      # Progams link staticlly
389
        'no_staticprogs'     => { 'STATIC_PROGS' , undef },    # Default
4034 dpurdie 390
        'noversiondll'       => { 'NO_VERSIONED_DLLS', 1 },    # Matches usage elsewhere
227 dpurdie 391
    );
392
 
393
    #
394
    #   Set default options
395
    #
396
    $::ScmCompilerOpts{'STATIC_PROGS'} = undef;
4034 dpurdie 397
    $::ScmCompilerOpts{'NO_VERSIONED_DLLS'} = undef;
398
 
399
    #
400
    #   Process toolset-specfic compiler options
401
    #
402
    if ( exists $GCCToolchain->{COMPILER_OPTIONS} )
403
    {
404
        CompileOptions('*', split(',',$GCCToolchain->{COMPILER_OPTIONS}) );
405
    }
227 dpurdie 406
}
407
 
4094 dpurdie 408
###############################################################################
409
#   ToolsetCTAGS()
410
#       This subroutine takes the user options and builds the rules
411
#       required to build the CTAGS database.
412
#
413
#   Arguments:
414
#       --xxx                   No arguments currently defined
415
#
416
#   Output:
417
#       [ctags:]
418
#           $(EXCTAGS)
419
#
420
###############################################################################
227 dpurdie 421
 
4094 dpurdie 422
sub ToolsetCTAGS
423
{
424
    EXCTAGS( @_ );
425
}
426
 
427
 
227 dpurdie 428
###############################################################################
429
#   ToolsetCC( $source, $obj, \@args )
430
#       This subroutine takes the user options and builds the rule(s)
431
#       required to compile the source file 'source' to 'obj'
432
#
433
###############################################################################
434
 
435
sub ToolsetCC
436
{
437
    my( $source, $obj, $pArgs ) = @_;
438
    my( $cflags, $file ) = "";
439
 
440
    foreach $_ ( @$pArgs ) {
441
        if (/--Shared$/) {                      # Building a 'shared' object
442
            $cflags  = "$cflags \$(SHCFLAGS)";
443
        } else {
444
            Message( "CC: unknown option $_ -- ignored\n" );
445
        }
446
    }
447
 
448
    MakePrint( "\n\t\$(CC)\n" );
449
    if ( $cflags )
450
    {                                           # object specific CFLAGS
451
        MakePadded( 4, "\$(OBJDIR)/$obj.$::o:" );
452
        MakePrint( "\tCFLAGS +=$cflags\n" );
453
    }
454
 
455
    $file = StripExt( $obj );                   # Metric working file
456
    ToolsetGenerate( "\$(OBJDIR)/$file.met" );
457
}
458
 
459
 
460
###############################################################################
461
#   ToolsetCCDepend( $depend, \@sources )
462
#       This subroutine takes the user options and builds the
463
#       rule(s) required to build the dependencies for the source
464
#       files 'sources' to 'depend'.
465
#
466
###############################################################################
467
 
468
sub ToolsetCCDepend
469
{
470
    MakePrint( "\t\$(CCDEPEND)\n" );
471
}
472
 
473
 
474
###############################################################################
475
#   ToolsetCXX( $source, $obj, \@args )
476
#       This subroutine takes the user options and builds the rule(s)
477
#       required to compile the source file 'source' to 'obj'
478
#
479
###############################################################################
480
 
481
sub ToolsetCXX
482
{
483
    my( $source, $obj, $pArgs ) = @_;
484
    my( $cflags, $file ) = "";
485
 
486
    foreach $_ ( @$pArgs ) {
487
        if (/--Shared$/) {                      # Building a 'shared' object
488
            $cflags  = "$cflags \$(SHCXXFLAGS)";
489
        } else {
490
            Message( "CXX: unknown option $_ -- ignored\n" );
491
        }
492
    }
493
 
494
    MakePrint( "\n\t\$(CXX)\n" );
495
    if ( $cflags )
496
    {                                           # object specific CFLAGS
497
        MakePadded( 4, "\$(OBJDIR)/$obj.$::o:" );
498
        MakePrint( "\tCXXFLAGS +=$cflags\n" );
499
    }
500
 
501
    $file = StripExt( $obj );                   # Metric working file
502
    ToolsetGenerate( "\$(OBJDIR)/$file.met" );
503
}
504
 
505
 
506
###############################################################################
507
#   ToolsetCXXDepend( $depend, \@sources )
508
#       This subroutine takes the user options and builds the
509
#       rule(s) required to build the dependencies for the source
510
#       files 'sources' to 'depend'.
511
#
512
###############################################################################
513
 
514
sub ToolsetCXXDepend
515
{
287 dpurdie 516
    ToolsetCCDepend();
227 dpurdie 517
}
518
 
519
 
520
###############################################################################
521
#   ToolsetAS( $source, $obj, \@args )
522
#       This subroutine takes the user options and builds the rule(s)
523
#       required to compile the source file 'source' to 'obj'
524
#
525
###############################################################################
526
 
527
sub ToolsetAS
528
{
529
    MakePrint( "\n\t\$(AS)\n" );
530
}
531
 
532
sub ToolsetASDepend
533
{
534
}
535
 
536
 
537
###############################################################################
538
#   ToolsetAR( $name, \@args, \@objs )
539
#       This subroutine takes the user options and builds the rules
540
#       required to build the library 'name'.
541
#
542
#   Arguments:
543
#       n/a
544
#
545
#   Output:
546
#       $(BINDIR)/name$.${a}:   .... ]
547
#           $(AR)
548
#
549
#       name_ld += ...  Linker command file
550
#           :
551
#
552
#       name_dp += ...  Dependency list
553
#           :
554
#
555
###############################################################################
556
 
557
sub ToolsetAR
558
{
559
    my( $name, $pArgs, $pObjs ) = @_;
560
 
561
#.. Parse arguments
562
#
563
    foreach $_ ( @$pArgs )
564
    {
565
        Message( "AR: unknown option $_ -- ignored\n" );
566
    }
567
 
568
#.. Target
569
#
570
    MakePrint( "#.. Library ($name)\n\n" );     # label
571
 
572
    MakeEntry( "\$(LIBDIR)/$name\$(GBE_TYPE).$::a:\t",
573
        "", "\\\n\t\t", ".$::o", @$pObjs );
574
 
575
#.. Build library rule (just append to standard rule)
576
#
577
    MakePrint( "\n\t\$(AR)\n\n" );
578
}
579
 
580
 
581
###############################################################################
582
#   ToolsetARMerge( $name, \@args, \@libs )
583
#       This subroutine takes the user options and builds the rules
584
#       required to build the library 'name' by merging the specified
585
#       libaries
586
#
587
#   Arguments:
588
#       --xxx                   No arguments currently defined
589
#
590
#   Output:
591
#       [ $(LIBDIR)/name$.${a}:   .... ]
592
#           ...
593
#
594
###############################################################################
595
 
596
sub ToolsetARMerge
597
{
598
    MakePrint( "\n\t\$(ARMERGE)\n\n" );
599
}
600
 
601
 
602
###############################################################################
289 dpurdie 603
#   ToolsetSHLD( $name, \@args, \@objs, \@libraries, $ver )
227 dpurdie 604
#       This subroutine takes the user options and builds the rules
339 dpurdie 605
#       required to link the Shared Library 'name'.
227 dpurdie 606
#
607
#   Arguments:
608
#   n/a
609
#
610
#   Output:
611
#       $(LIBDIR)/name:     $(LIBDIR)/shared
612
#           ln -s $shared $name
613
#
614
#       $(LIBDIR)/name.dep: $(GBE_OBJDIR)
615
#       $(LIBDIR)/name.dep: $(GBE_LIBDIR)
616
#       $(LIBDIR)/name.dep: $(GBE_PLATFORM).mk
617
#           $(SHLDDEPEND)
618
#
619
#       $(LIBDIR)/shared:   SHNAME=name
620
#       $(LIBDIR)/shared:   SHBASE=base
621
#       $(LIBDIR)/shared:   $(LIBDIR)/name.dep  \
622
#           $(OBJECTS)
623
#                           
624
#       ifneq "$(findstring $(IFLAG),23)" ""
625
#       -include            "$(LIBDIR)/name.dep"
626
#       endif
627
#
628
#       name_ld += ...
629
#           :
630
#
631
###############################################################################
632
 
633
sub ToolsetSHLD
634
{
289 dpurdie 635
    my( $name, $pArgs, $pObjs, $pLibs, $ver ) = @_;
373 dpurdie 636
    my( $linkname, $soname, $shared, $dbgname, $def, $def_pref, $multi_scan );
4034 dpurdie 637
    my $sosuffix;
638
    my $noVersionedLib = $::ScmCompilerOpts{'NO_VERSIONED_DLLS'};
227 dpurdie 639
 
4034 dpurdie 640
 
227 dpurdie 641
#.. Parse arguments
642
#
643
    foreach $_ ( @$pArgs )
644
    {
645
        if (/^--Def=(.*?)(\,(.*))?$/) {         # Library definition
646
            #
647
            #   Locate the Def file.
648
            #   If it is a generate file so it will be in the SRCS hash
649
            #   Otherwise the user will have to use Src to locate the file
650
            #
651
            $def = MakeSrcResolve($1);
652
            $def_pref = '';
653
            if ( $1 =~ m~\.def$~ ) {
654
                $def_pref = '--version-script='; # Old def file
655
            }
656
        } elsif ( /^--MultiScan/i ) {
657
            $multi_scan = 1;
658
 
659
        } elsif ( /^--NoMultiScan/i ) {
660
            $multi_scan = 0;
661
 
339 dpurdie 662
        } elsif ( /^--SoNameSuffix=(.*)/i ) {
663
            $sosuffix = $1;
664
 
4034 dpurdie 665
        } elsif (/^--NoVersionDll/i) {
666
            $noVersionedLib = 1;
667
 
227 dpurdie 668
        } else {
669
            Message( "SHLD: unknown option $_ -- ignored\n" );
670
        }
671
    }
672
 
4034 dpurdie 673
    #
674
    # Determine the 'soname' in none has been provided
675
    #
676
    $sosuffix = '.' . $ver
677
        unless ( defined $sosuffix );
678
    $sosuffix = ''
679
        if ( $noVersionedLib );
680
 
339 dpurdie 681
#.. Various library names
227 dpurdie 682
#
339 dpurdie 683
    $linkname = "$name\$(GBE_TYPE).$::so";
4034 dpurdie 684
    $shared = $noVersionedLib ? $linkname : "$linkname.$ver";
339 dpurdie 685
    $soname = "$linkname$sosuffix";
4034 dpurdie 686
 
373 dpurdie 687
    my $shared_path = "\$(LIBDIR)/${shared}";
688
    my $dbg_path =  $shared_path . '.dbg';
227 dpurdie 689
 
690
#.. Cleanup rules
691
#
692
#   map     Map file
693
#   ln      Link from LIBDIR to BINDIR
694
#
261 dpurdie 695
    ToolsetGenerate( "\$(LIBDIR)/${name}.map" );
696
    ToolsetGenerate( "\$(LIBDIR)/${shared}" );
339 dpurdie 697
    ToolsetGenerate( "\$(BINDIR)/${soname}" );
373 dpurdie 698
    ToolsetGenerate( $dbg_path );
227 dpurdie 699
 
700
#.. Build rules
701
#
702
#   name        Base name
703
#   shared      Library name, includes GBE_TYPE specification
704
#
705
    my ($io) = ToolsetPrinter::New();
335 dpurdie 706
    my $dep = $io->SetShldTarget($shared);
227 dpurdie 707
 
708
    $io->Label( "Shared library", $name );
339 dpurdie 709
    PackageShlibAddFiles( $name, "\$(LIBDIR)/$shared" );
373 dpurdie 710
    PackageShlibAddFiles( $name, $dbg_path );
4034 dpurdie 711
 
227 dpurdie 712
    $io->Prt( "\$(LIBDIR)/${shared}:\tSHBASE=${name}\n" );
339 dpurdie 713
    $io->Prt( "\$(LIBDIR)/${shared}:\tSHNAME=${soname}\n" );
714
    $io->Prt( "\$(LIBDIR)/${shared}: \\\n\t\t${dep}" );
321 dpurdie 715
    $io->Entry( "", "", " \\\n\t\t", ".$::o", @$pObjs );
227 dpurdie 716
    $io->Prt( "\\\n\t\t$def" ) if($def);
373 dpurdie 717
    $io->Prt( "\n\t\$(SHLD)" );
718
    $io->Prt( "\n\t\$(call LDSTRIP,$shared_path,$dbg_path)\n\n" );
321 dpurdie 719
 
339 dpurdie 720
#
721
#   Create soft links
722
#       'Real Name' to its 'Link Name'
723
#       'Real Name' to 'SoName' in the BINDIR (for testing I think)
724
#       'Real Name' to 'SoName' in the LIBDIR (if different)
725
#
4034 dpurdie 726
    if ( $shared ne $linkname)
727
    {
728
        $io->Label( "Shared library Symbolic Links", $name );
729
        PackageShlibAddFiles( $name, "\$(LIBDIR)/$linkname" );
730
        $io->Prt( "\$(LIBDIR)/$linkname:\t\\\n" .
731
                  "\t\t\$(GBE_BINDIR)\\\n" .
732
                  "\t\t\$(LIBDIR)/${shared}\n" .
733
                  "\t\$(AA_PRE)(rm -f \$@; ln -s ./$shared \$@)\n\n" );
734
    }
735
 
736
    $io->Label( "Shared library BINDIR Symbolic Links", $name );
737
    PackageShlibAddFiles( $name, "\$(BINDIR)/$soname" );
738
    $io->Prt( "\$(BINDIR)/$soname:\t\\\n" .
339 dpurdie 739
              "\t\t\$(GBE_BINDIR)\\\n" .
740
              "\t\t\$(LIBDIR)/${shared}\n" .
4034 dpurdie 741
              "\t\$(AA_PRE)(rm -f \$@; ln -s ../\$(LIBDIR)/$shared \$@)\n\n" );
339 dpurdie 742
 
4034 dpurdie 743
    if ( $soname ne $shared )
339 dpurdie 744
    {
745
        $io->Label( "Shared library SoName Symbolic Links", $name );
746
        PackageShlibAddFiles( $name, "\$(LIBDIR)/$soname" );
747
        $io->Prt( "\$(LIBDIR)/$soname:\t\\\n" .
748
                  "\t\t\$(GBE_LIBDIR)\\\n" .
749
                  "\t\t\$(LIBDIR)/${shared}\n" .
750
                  "\t\$(AA_PRE)(rm -f \$@; ln -s ./$shared \$@)\n" );
751
    }
752
 
227 dpurdie 753
#.. Linker command file
754
#
755
#       Now the fun part... piecing together a variable $(name_shld)
756
#       which ends up in the command file.
757
#
339 dpurdie 758
    $io->Newline();
227 dpurdie 759
    $io->SetTag( "${name}_shld" );              # command tag
760
    $io->SetTerm( "\n" );
761
 
762
    $io->Label( "Linker commands", $name );     # label
763
 
764
                                                # object list
765
    $io->ObjList( $name, $pObjs, \&ToolsetObjRecipe );
766
 
767
    ToolsetLibStd( $pLibs );                    # push standard libraries
768
 
769
    $io->Cmd( "-Wl,$def_pref$def" ) if ($def);
770
 
771
    $io->Cmd( "-Wl,--start-group" ) if ($multi_scan);
772
    $io->LibList( $name, $pLibs, \&ToolsetLibRecipe );
773
    $io->Cmd( "-Wl,--end-group" ) if ($multi_scan);
774
 
775
    $io->Newline();
776
 
335 dpurdie 777
    #.. Dependency link,
778
    #   Create a library dependency file
779
    #       Create command file to build applicaton dependency list
780
    #       from the list of dependent libraries
781
    #
782
    #       Create makefile directives to include the dependency
783
    #       list into the makefile.
784
    #
785
    $io->DepRules( $pLibs, \&ToolsetLibRecipe, "\$(LIBDIR)/${shared}" );
339 dpurdie 786
    $io->SHLDDEPEND($name, $soname);
227 dpurdie 787
}
788
 
789
 
790
###############################################################################
271 dpurdie 791
# Function        : ToolsetLD
227 dpurdie 792
#
271 dpurdie 793
# Description     : Takes the user options and builds the rules required to
794
#                   link the program 'name'.
227 dpurdie 795
#
271 dpurdie 796
# Inputs          : $name           - base name of the program
797
#                   $pArgs          - Ref to program arguments
798
#                   $pObjs          - Ref to program objects
799
#                   $pLibs          - Ref to program library list
227 dpurdie 800
#
271 dpurdie 801
# Returns         : Nothing
227 dpurdie 802
#
271 dpurdie 803
# Output:         : Rules and recipes to create a program
804
#                       Create program rules and recipes
805
#                       Create linker input script
806
#                       Create library dependency list
807
#                       Include library dependency information
227 dpurdie 808
#
809
sub ToolsetLD
810
{
811
    my( $name, $pArgs, $pObjs, $pLibs ) = @_;
812
    my $static = $::ScmCompilerOpts{'STATIC_PROGS'};
813
    my $multi_scan;
814
 
815
#.. Parse arguments
816
#
817
    foreach $_ ( @$pArgs )
818
    {
819
        if ( m/^--Static$/ ) {
820
            $static = 1;
821
 
822
        } elsif ( m/^--Shared/ ) {
823
            $static = 0;
824
 
825
        } elsif ( /^--MultiScan/i ) {
826
            $multi_scan = 1;
827
 
828
        } elsif ( /^--NoMultiScan/i ) {
829
            $multi_scan = 0;
830
 
831
        } else {
832
            Message( "LD: unknown option $_ -- ignored\n" );
833
        }
834
    }
835
 
271 dpurdie 836
#.. Names of programs and components
837
#
838
    my $base = "\$(BINDIR)/${name}";
839
    my $full = $base . $::exe;
840
    my $map  = $base . '.map';
841
    my $ld  =  $base . '.ld';
373 dpurdie 842
    my $dbg =  $base . '.dbg';
271 dpurdie 843
 
227 dpurdie 844
#.. Cleanup rules
845
#
271 dpurdie 846
    ToolsetGenerate( $ld );
847
    ToolsetGenerate( $map );
373 dpurdie 848
    ToolsetGenerate( $dbg );
227 dpurdie 849
 
850
#.. Build rules
851
#
852
    my ($io) = ToolsetPrinter::New();
335 dpurdie 853
    my $dep = $io->SetLdTarget( $name );
227 dpurdie 854
 
271 dpurdie 855
    $io->Prt( "$full : $dep " );
856
    $io->Entry( "", "", "\\\n\t", ".$::o ", @$pObjs );
373 dpurdie 857
    $io->Prt( "\n\t\$(LD)" );
858
    $io->Prt( "\n\t\$(call LDSTRIP,$full,$dbg)\n\n" );
227 dpurdie 859
 
271 dpurdie 860
 
227 dpurdie 861
#.. Linker command file
862
#
863
#       Now the fun part... piecing together a variable $(name_ld)
864
#       which ends up in the command file.
865
#
866
    $io->SetTag( "${name}_ld" );                # macro tag
867
    $io->SetTerm( "\n" );
868
 
869
    $io->Label( "Linker commands", $name );     # label
870
 
871
    $io->Cmd( "-static" ) if ($static);         # Link as a static program
872
 
873
                                                # object list
874
    $io->ObjList( $name, $pObjs, \&ToolsetObjRecipe );
875
 
876
    ToolsetLibStd( $pLibs );                    # push standard libraries
877
 
878
                                                # library list
879
    $io->Cmd( "-Wl,--start-group" ) if ($multi_scan);
880
    $io->LibList( $name, $pLibs, \&ToolsetLibRecipe );
881
    $io->Cmd( "-Wl,--end-group" ) if ($multi_scan);
882
 
883
    $io->Newline();
884
 
335 dpurdie 885
    #.. Dependency link,
886
    #   Create a library dependency file
887
    #       Create command file to build applicaton dependency list
888
    #       from the list of dependent libraries
889
    #
890
    #       Create makefile directives to include the dependency
891
    #       list into the makefile.
892
    #
893
    $io->DepRules( $pLibs, \&ToolsetLibRecipe, $base );
894
    $io->LDDEPEND();
271 dpurdie 895
 
896
#.. Package up the program and other artifacts
897
#
898
    PackageProgAddFiles ( $name, $full );
373 dpurdie 899
    PackageProgAddFiles ( $name, $dbg );
271 dpurdie 900
 
227 dpurdie 901
}
902
 
903
 
904
########################################################################
905
#
906
#   Push standard "system" libraries. This is a helper function
907
#   used within this toolset.
908
#
909
#   Arguments:
910
#       $plib       Reference to library array.
911
#
912
########################################################################
913
 
914
sub ToolsetLibStd
915
{
916
}
917
 
918
 
919
########################################################################
920
#
921
#   Generate a linker object recipe.  This is a helper function used 
922
#   within this toolset.
923
#
924
#   Arguments:
925
#       $io         I/O stream
926
#
927
#       $target     Name of the target
928
#
929
#       $obj        Library specification
930
#
931
########################################################################
932
 
933
sub ToolsetObjRecipe
934
{
935
    my ($io, $target, $obj) = @_;
936
 
937
    $io->Cmd( "\$(strip $obj).$::o" );
938
}
939
 
940
 
941
###############################################################################
942
#
943
#   Parse a linker lib list
944
#   This is a helper function used within this toolset
945
#
946
#   Arguments:
947
#       $target     Name of the target
948
#
949
#       $lib        Library specification
950
#
951
#       $tag        Tag (user specified)
952
#
953
#       $dp         If building a depend list, the full target name.
954
#
955
###############################################################################
956
 
957
sub ToolsetLibRecipe
958
{
959
    my ($io, $target, $lib, $dp) = @_;
960
 
961
    if ( ! defined($dp) ) {                     # linker
962
        $lib =~ s/^lib//;                       # .. remove leading 'lib'
963
        $io->Cmd( "-l$lib" );
964
 
965
    } else {                                    # depend
966
        $io->Cmd( "$dp:\t@(vlib2,$lib,GCC_LIB)" );
967
 
968
    }
969
}
970
 
971
#.. Successful termination
972
1;
973