Subversion Repositories DevTools

Rev

Rev 4699 | Rev 4701 | 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
 
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
 
4700 alewis 129
my $UseGcov = 0;
130
 
227 dpurdie 131
##############################################################################
132
#   ToolsetInit()
133
#       Runtime initialisation
134
#
135
##############################################################################
136
 
137
ToolsetInit();
138
 
139
sub ToolsetInit
140
{
4034 dpurdie 141
    my( $GCCTarget, $GCCToolchain, $GCCRoot, $GCCBin, $GCCAr, $GCCObjCopy );
4700 alewis 142
    my( $GCCFlags,  $GCCFlagsP, $GCCFlagsD, $LDFlags );
3967 dpurdie 143
    my( $PkgArch);
4034 dpurdie 144
    my( $arg_alias, $tools_found, $compiler_tool );
227 dpurdie 145
 
146
#.. Toolset configuration
147
#
148
    $::ScmToolsetVersion = "1.0.0";             # our version
149
    $::ScmToolsetGenerate = 0;                  # GEN generate optional
150
    $::ScmToolsetCompilerPath = 1;              # Exports Compiler path to makefile via SCM_COMPILERPATH
271 dpurdie 151
    $::ScmToolsetProgDependancies = 0;          # handle Prog dependancies myself
339 dpurdie 152
    $::ScmToolsetSoName = 1;                    # Shared library supports SoName
227 dpurdie 153
 
154
#.. Standard.rul requirements
155
#
156
    $::s = "asm";
157
    $::o = "o";
158
    $::so = "so";
159
    $::a = "a";
160
    $::exe = "";
161
 
162
#.. Parse arguments
163
#
164
    foreach $_ ( @::ScmToolsetArgs ) {
165
        if (/^--Target=(.*)/) {                 # OS Version
166
            $GCCTarget = "$1";
167
 
168
        } elsif (/^--CrossAlias=(.*)/) {        # CrossCompiler target-alias
169
            $arg_alias = $1;
170
 
4700 alewis 171
        } elsif (/^--UseGcov/) {                # Compile for code coverage
172
            $UseGcov = 1;
173
 
4034 dpurdie 174
        } elsif (/^--CompilerTool=(.*)/) {      # CrossCompiler located in package
175
            $compiler_tool = $1;
176
 
227 dpurdie 177
        } else {
178
            Message( "gcc toolset: unknown option $_ -- ignored\n" );
179
        }
180
    }
181
 
182
    foreach $_ ( @::ScmPlatformArgs ) {
183
        if (/^--product=(.*)/) {                # GBE product
184
 
185
        } else {
186
            Message( "gcc toolset: unknown platform argument $_ -- ignored\n" );
187
        }
188
    }
189
 
190
    Error ("TOOLSET/gcc - Target undefined" )
191
        unless ($GCCTarget);
192
 
4034 dpurdie 193
    #
194
    #   If the toolset is not required, then do not process any futher
195
    #   We may not find the compiler
196
    #
197
    return
198
        if ($ScmNoToolsTest);
199
 
227 dpurdie 200
#.. Cross compile support
4034 dpurdie 201
#   Compiler provided in package, rather than install on machine
227 dpurdie 202
#
4034 dpurdie 203
if ( $compiler_tool  )
204
{
205
    #
206
    #   The GCC toolset will handle a compiler provided within a package
207
    #   Initial requirement was for ANDROID NDKs where the compiler is
208
    #   a part of the NDK and will change.
209
    #
210
    #   Compilers in packages will have a file in gbe/COMPILERS/<compiler_tool>
211
    #   that contains data specifically designed for this toolset
212
    #
213
    Verbose("Locate compiler in package: $compiler_tool");
214
    my @toolList;
215
    my $toolPath;
216
    my $toolPkg;
217
    for my $entry (@{$::ScmBuildPkgRules{$ScmPlatform} })
218
    {
219
        my $tpath = join('/', $entry->{ROOT}, 'gbe', 'COMPILERS' , $compiler_tool);
220
        if ( -f $tpath  )
221
        {
222
            push @toolList, $entry->{NAME};
223
            $toolPath = $tpath;
224
            $toolPkg = $entry;
225
        }
226
    }
227
    Error ("Multiple packages provide required compiler:", @toolList)
228
        if ( scalar(@toolList) > 1 );
229
    Error ("Required compiler not found in any package", "Compiler: $compiler_tool")
230
        unless ( scalar(@toolList) == 1 );
231
 
232
    #
233
    #   Process the compiler info file
234
    #   Rip out the data and create a hash of item/values
235
    #   File format:
236
    #       '#' is a line comment
237
    #       item=value
238
    #
239
    my %data;
240
    open (my $DATA, '<', $toolPath ) || Error("Cannot open compiler datafile. $!", "File: $toolPath");
241
    while ( <$DATA> )
242
    {
243
        $_ =~ s~\s+$~~;
244
        next if ( m~^#~ );
245
        m~(.*?)\s*=\s*(.*)~;
246
        $data{$1} = $2;
247
    }
248
    close $DATA;
249
 
250
    #
251
    #   Force this compilers data into the ToolsetConfig hash
252
    #
253
    $arg_alias = $compiler_tool;
254
    %ToolsetConfig = ();
255
 
256
    $ToolsetConfig{$arg_alias}{ROOT} = join('/', $toolPkg->{ROOT}, $data{ROOT} );
257
    $ToolsetConfig{$arg_alias}{BASE} = $data{BASE} . '-';
258
    $ToolsetConfig{$arg_alias}{CC_OPTS} = $data{CFLAGS};
259
    $ToolsetConfig{$arg_alias}{CC_OPTSP} = $data{CFLAGSP};
260
    $ToolsetConfig{$arg_alias}{CC_OPTSD} = $data{CFLAGSD};
261
    $ToolsetConfig{$arg_alias}{VERSION} = $data{VERSION};
262
    $ToolsetConfig{$arg_alias}{MACHINE} = $data{MACHINE};
263
    $ToolsetConfig{$arg_alias}{COMPILER_OPTIONS} = $data{COMPILER_OPTIONS};
264
}
265
 
266
#.. Cross compile support
267
#
227 dpurdie 268
#   Toolchain=root,[bin]
269
#
270
    if ( $arg_alias )
271
    {
272
        if ( exists $ToolsetConfig{ $arg_alias } )
273
        {
369 dpurdie 274
            $GCCToolchain = $ToolsetConfig{ $arg_alias };
275
            $tools_found = (-d $GCCToolchain->{ROOT});
227 dpurdie 276
            Warning ("gcc toolset: CrossPlatform toolchain not found for: $arg_alias",
369 dpurdie 277
                     "Path: $GCCToolchain->{ROOT}" ) unless $tools_found;
227 dpurdie 278
        }
279
        else
280
        {
281
            Error("gcc toolset: CrossPlatform Alias not configured: $arg_alias");
282
        }
369 dpurdie 283
 
284
        Warning ("Uncontrolled toolchain used: $arg_alias")
285
            if ( exists($GCCToolchain->{UNCONTROLLED}) && $GCCToolchain->{UNCONTROLLED} );
227 dpurdie 286
    }
287
 
288
    #
289
    #   If no Cross compiler toolchain is found (preferred method), then attempt
290
    #   to match a native compiler. Only known targets allow a native build
291
    #
292
    unless ( $tools_found )
293
    {
294
        if ( exists ( $NativeCompilers{$GCCTarget} ))
295
        {
296
            if ( $NativeCompilers{$GCCTarget} eq $::GBE_MACHTYPE )
297
            {
298
                $tools_found = 1;
369 dpurdie 299
                $GCCToolchain = undef;
227 dpurdie 300
            }
301
        }
302
    }
303
 
304
    #
305
    #   Must have a toolset by now, either a cross compiler or Native
306
    #
307
    Error ("gcc toolset: Toolchain not found for: $GCCTarget" )
308
        unless ( $tools_found );
309
 
310
 
369 dpurdie 311
    if ( defined $GCCToolchain )
227 dpurdie 312
    {
313
        #
369 dpurdie 314
        #   Parse GCCToolchain. Potential parts to create
315
        #       GCCRoot     - Location to find the effective /usr/include directory
316
        #       GCCBin      - Path to the gcc executable
317
        #       GCCAr       - Path to the ar executable
4034 dpurdie 318
        #       GCCFlags    - Additional compiler flags. Also Production and Debug
227 dpurdie 319
        #
369 dpurdie 320
        $GCCRoot = $GCCToolchain->{ROOT};
321
        $GCCBin = '${GCC_ROOT}/' . $GCCToolchain->{BASE} . 'gcc';
322
        $GCCAr =  '${GCC_ROOT}/' . $GCCToolchain->{BASE} . 'ar';
373 dpurdie 323
        $GCCObjCopy =  '${GCC_ROOT}/' . $GCCToolchain->{BASE} . 'objcopy';
369 dpurdie 324
        $GCCFlags = $GCCToolchain->{CC_OPTS};
4034 dpurdie 325
        $GCCFlagsP = $GCCToolchain->{CC_OPTSP};
326
        $GCCFlagsD = $GCCToolchain->{CC_OPTSD};
3967 dpurdie 327
        $PkgArch = $GCCToolchain->{PACKAGE_ARCH};
227 dpurdie 328
    }
329
    else
330
    {
373 dpurdie 331
        $GCCRoot = '/usr';
332
        $GCCBin = 'gcc';
333
        $GCCAr = 'ar';
334
        $GCCObjCopy =  'objcopy';
227 dpurdie 335
    }
4700 alewis 336
 
337
    #
338
    #   When running under gcov we need to instruct GCC to perform code coverage
339
    #   generation in both C flags and LD flags
340
    #
341
    if ( $UseGcov )
342
    {
343
        $GCCFlags=$GCCFlags . ' -coverage';
344
        $LDFlags=$LDFlags . ' -coverage';
345
    }
346
 
227 dpurdie 347
 
348
#.. Define GCC environment
349
#
350
    PlatformDefine( "
351
#################################################
352
# GCC toolchain definitions 
353
#
354
#..");
369 dpurdie 355
    PlatformDefine( "GCC_TARGET         := $GCCTarget" );
356
    PlatformDefine( "GCC_ROOT           := $GCCRoot" );
357
    PlatformDefine( "GCC_CC             := $GCCBin" );
358
    PlatformDefine( "GCC_AR             := $GCCAr" );
373 dpurdie 359
    PlatformDefine( "GCC_OBJCOPY        := $GCCObjCopy" );
369 dpurdie 360
    PlatformDefine( "GCC_CFLAGS         := $GCCFlags" ) if defined $GCCFlags;
4034 dpurdie 361
    PlatformDefine( "GCC_CFLAGSP        := $GCCFlagsP" ) if defined $GCCFlagsP;
362
    PlatformDefine( "GCC_CFLAGSD        := $GCCFlagsD" ) if defined $GCCFlagsD;
4700 alewis 363
    PlatformDefine( "GCC_LDFLAGS        := $LDFlags" ) if defined $LDFlags;
369 dpurdie 364
 
227 dpurdie 365
    #
366
    #   Required since this toolset advertises: ScmToolsetCompilerPath
367
    #
369 dpurdie 368
    PlatformDefine( "SCM_COMPILERPATH   := \$\{GCC_CC\}" );
3967 dpurdie 369
 
370
    #
371
    #   Sanity checking
372
    #
373
    PlatformDefine( "GCC_EVERSION       := " . $GCCToolchain->{VERSION} ) if defined $GCCToolchain->{VERSION};
374
    PlatformDefine( "GCC_EMACHINE       := " . $GCCToolchain->{MACHINE} ) if defined $GCCToolchain->{MACHINE};
375
 
376
    #
377
    #   Option indication of packaging architecture
378
    #   Used by non-embedded systems for packaging. See debian_packager
379
    #
380
    PlatformDefine( "PACKAGE_ARCH       := $PkgArch" ) if (defined $PkgArch);
369 dpurdie 381
    PlatformDefine( "" );
227 dpurdie 382
 
383
#.. Piece the world together
384
#
3967 dpurdie 385
    Init( 'gcc' );
227 dpurdie 386
    ToolsetDefines( "gcc.def" );
387
    ToolsetRules( "gcc.rul" );
388
    ToolsetRules( "standard.rul" );
389
 
4094 dpurdie 390
 
391
    PlatformDefine( "CTAGS_EXE:= ctags" );
392
    ToolsetRequire( "exctags" );                # and Exuberant Ctags
393
 
227 dpurdie 394
#   Create a standard data structure
395
#   This is a hash of hashes
396
#       The first hash is keyed by CompileOption keyword
397
#       The second hash contains pairs of values to set or remove
398
#
399
    %::ScmToolsetCompilerOptions =
400
    (
401
        #
402
        #   Control the thread model to use
403
        #   This will affect the compiler options and the linker options
404
        #
405
        'staticprogs'        => { 'STATIC_PROGS' , '1' },      # Progams link staticlly
406
        'no_staticprogs'     => { 'STATIC_PROGS' , undef },    # Default
4034 dpurdie 407
        'noversiondll'       => { 'NO_VERSIONED_DLLS', 1 },    # Matches usage elsewhere
227 dpurdie 408
    );
409
 
410
    #
411
    #   Set default options
412
    #
413
    $::ScmCompilerOpts{'STATIC_PROGS'} = undef;
4034 dpurdie 414
    $::ScmCompilerOpts{'NO_VERSIONED_DLLS'} = undef;
415
 
416
    #
417
    #   Process toolset-specfic compiler options
418
    #
419
    if ( exists $GCCToolchain->{COMPILER_OPTIONS} )
420
    {
421
        CompileOptions('*', split(',',$GCCToolchain->{COMPILER_OPTIONS}) );
422
    }
227 dpurdie 423
}
424
 
4094 dpurdie 425
###############################################################################
426
#   ToolsetCTAGS()
427
#       This subroutine takes the user options and builds the rules
428
#       required to build the CTAGS database.
429
#
430
#   Arguments:
431
#       --xxx                   No arguments currently defined
432
#
433
#   Output:
434
#       [ctags:]
435
#           $(EXCTAGS)
436
#
437
###############################################################################
227 dpurdie 438
 
4094 dpurdie 439
sub ToolsetCTAGS
440
{
441
    EXCTAGS( @_ );
442
}
443
 
444
 
227 dpurdie 445
###############################################################################
446
#   ToolsetCC( $source, $obj, \@args )
447
#       This subroutine takes the user options and builds the rule(s)
448
#       required to compile the source file 'source' to 'obj'
449
#
450
###############################################################################
451
 
452
sub ToolsetCC
453
{
454
    my( $source, $obj, $pArgs ) = @_;
455
    my( $cflags, $file ) = "";
456
 
457
    foreach $_ ( @$pArgs ) {
458
        if (/--Shared$/) {                      # Building a 'shared' object
459
            $cflags  = "$cflags \$(SHCFLAGS)";
460
        } else {
461
            Message( "CC: unknown option $_ -- ignored\n" );
462
        }
463
    }
464
 
465
    MakePrint( "\n\t\$(CC)\n" );
466
    if ( $cflags )
467
    {                                           # object specific CFLAGS
468
        MakePadded( 4, "\$(OBJDIR)/$obj.$::o:" );
469
        MakePrint( "\tCFLAGS +=$cflags\n" );
470
    }
471
 
472
    $file = StripExt( $obj );                   # Metric working file
473
    ToolsetGenerate( "\$(OBJDIR)/$file.met" );
474
}
475
 
476
 
477
###############################################################################
478
#   ToolsetCCDepend( $depend, \@sources )
479
#       This subroutine takes the user options and builds the
480
#       rule(s) required to build the dependencies for the source
481
#       files 'sources' to 'depend'.
482
#
483
###############################################################################
484
 
485
sub ToolsetCCDepend
486
{
487
    MakePrint( "\t\$(CCDEPEND)\n" );
488
}
489
 
490
 
491
###############################################################################
492
#   ToolsetCXX( $source, $obj, \@args )
493
#       This subroutine takes the user options and builds the rule(s)
494
#       required to compile the source file 'source' to 'obj'
495
#
496
###############################################################################
497
 
498
sub ToolsetCXX
499
{
500
    my( $source, $obj, $pArgs ) = @_;
501
    my( $cflags, $file ) = "";
502
 
503
    foreach $_ ( @$pArgs ) {
504
        if (/--Shared$/) {                      # Building a 'shared' object
505
            $cflags  = "$cflags \$(SHCXXFLAGS)";
506
        } else {
507
            Message( "CXX: unknown option $_ -- ignored\n" );
508
        }
509
    }
510
 
511
    MakePrint( "\n\t\$(CXX)\n" );
512
    if ( $cflags )
513
    {                                           # object specific CFLAGS
514
        MakePadded( 4, "\$(OBJDIR)/$obj.$::o:" );
515
        MakePrint( "\tCXXFLAGS +=$cflags\n" );
516
    }
517
 
518
    $file = StripExt( $obj );                   # Metric working file
519
    ToolsetGenerate( "\$(OBJDIR)/$file.met" );
520
}
521
 
522
 
523
###############################################################################
524
#   ToolsetCXXDepend( $depend, \@sources )
525
#       This subroutine takes the user options and builds the
526
#       rule(s) required to build the dependencies for the source
527
#       files 'sources' to 'depend'.
528
#
529
###############################################################################
530
 
531
sub ToolsetCXXDepend
532
{
287 dpurdie 533
    ToolsetCCDepend();
227 dpurdie 534
}
535
 
536
 
537
###############################################################################
538
#   ToolsetAS( $source, $obj, \@args )
539
#       This subroutine takes the user options and builds the rule(s)
540
#       required to compile the source file 'source' to 'obj'
541
#
542
###############################################################################
543
 
544
sub ToolsetAS
545
{
546
    MakePrint( "\n\t\$(AS)\n" );
547
}
548
 
549
sub ToolsetASDepend
550
{
551
}
552
 
553
 
554
###############################################################################
555
#   ToolsetAR( $name, \@args, \@objs )
556
#       This subroutine takes the user options and builds the rules
557
#       required to build the library 'name'.
558
#
559
#   Arguments:
560
#       n/a
561
#
562
#   Output:
563
#       $(BINDIR)/name$.${a}:   .... ]
564
#           $(AR)
565
#
566
#       name_ld += ...  Linker command file
567
#           :
568
#
569
#       name_dp += ...  Dependency list
570
#           :
571
#
572
###############################################################################
573
 
574
sub ToolsetAR
575
{
576
    my( $name, $pArgs, $pObjs ) = @_;
577
 
578
#.. Parse arguments
579
#
580
    foreach $_ ( @$pArgs )
581
    {
582
        Message( "AR: unknown option $_ -- ignored\n" );
583
    }
584
 
585
#.. Target
586
#
587
    MakePrint( "#.. Library ($name)\n\n" );     # label
588
 
589
    MakeEntry( "\$(LIBDIR)/$name\$(GBE_TYPE).$::a:\t",
590
        "", "\\\n\t\t", ".$::o", @$pObjs );
591
 
592
#.. Build library rule (just append to standard rule)
593
#
594
    MakePrint( "\n\t\$(AR)\n\n" );
595
}
596
 
597
 
598
###############################################################################
599
#   ToolsetARMerge( $name, \@args, \@libs )
600
#       This subroutine takes the user options and builds the rules
601
#       required to build the library 'name' by merging the specified
602
#       libaries
603
#
604
#   Arguments:
605
#       --xxx                   No arguments currently defined
606
#
607
#   Output:
608
#       [ $(LIBDIR)/name$.${a}:   .... ]
609
#           ...
610
#
611
###############################################################################
612
 
613
sub ToolsetARMerge
614
{
615
    MakePrint( "\n\t\$(ARMERGE)\n\n" );
616
}
617
 
618
 
619
###############################################################################
289 dpurdie 620
#   ToolsetSHLD( $name, \@args, \@objs, \@libraries, $ver )
227 dpurdie 621
#       This subroutine takes the user options and builds the rules
339 dpurdie 622
#       required to link the Shared Library 'name'.
227 dpurdie 623
#
624
#   Arguments:
625
#   n/a
626
#
627
#   Output:
628
#       $(LIBDIR)/name:     $(LIBDIR)/shared
629
#           ln -s $shared $name
630
#
631
#       $(LIBDIR)/name.dep: $(GBE_OBJDIR)
632
#       $(LIBDIR)/name.dep: $(GBE_LIBDIR)
633
#       $(LIBDIR)/name.dep: $(GBE_PLATFORM).mk
634
#           $(SHLDDEPEND)
635
#
636
#       $(LIBDIR)/shared:   SHNAME=name
637
#       $(LIBDIR)/shared:   SHBASE=base
638
#       $(LIBDIR)/shared:   $(LIBDIR)/name.dep  \
639
#           $(OBJECTS)
640
#                           
641
#       ifneq "$(findstring $(IFLAG),23)" ""
642
#       -include            "$(LIBDIR)/name.dep"
643
#       endif
644
#
645
#       name_ld += ...
646
#           :
647
#
648
###############################################################################
649
 
650
sub ToolsetSHLD
651
{
289 dpurdie 652
    my( $name, $pArgs, $pObjs, $pLibs, $ver ) = @_;
373 dpurdie 653
    my( $linkname, $soname, $shared, $dbgname, $def, $def_pref, $multi_scan );
4034 dpurdie 654
    my $sosuffix;
655
    my $noVersionedLib = $::ScmCompilerOpts{'NO_VERSIONED_DLLS'};
227 dpurdie 656
 
4034 dpurdie 657
 
227 dpurdie 658
#.. Parse arguments
659
#
660
    foreach $_ ( @$pArgs )
661
    {
662
        if (/^--Def=(.*?)(\,(.*))?$/) {         # Library definition
663
            #
664
            #   Locate the Def file.
665
            #   If it is a generate file so it will be in the SRCS hash
666
            #   Otherwise the user will have to use Src to locate the file
667
            #
668
            $def = MakeSrcResolve($1);
669
            $def_pref = '';
670
            if ( $1 =~ m~\.def$~ ) {
671
                $def_pref = '--version-script='; # Old def file
672
            }
673
        } elsif ( /^--MultiScan/i ) {
674
            $multi_scan = 1;
675
 
676
        } elsif ( /^--NoMultiScan/i ) {
677
            $multi_scan = 0;
678
 
339 dpurdie 679
        } elsif ( /^--SoNameSuffix=(.*)/i ) {
680
            $sosuffix = $1;
681
 
4034 dpurdie 682
        } elsif (/^--NoVersionDll/i) {
683
            $noVersionedLib = 1;
684
 
227 dpurdie 685
        } else {
686
            Message( "SHLD: unknown option $_ -- ignored\n" );
687
        }
688
    }
689
 
4034 dpurdie 690
    #
691
    # Determine the 'soname' in none has been provided
692
    #
693
    $sosuffix = '.' . $ver
694
        unless ( defined $sosuffix );
695
    $sosuffix = ''
696
        if ( $noVersionedLib );
697
 
339 dpurdie 698
#.. Various library names
227 dpurdie 699
#
339 dpurdie 700
    $linkname = "$name\$(GBE_TYPE).$::so";
4034 dpurdie 701
    $shared = $noVersionedLib ? $linkname : "$linkname.$ver";
339 dpurdie 702
    $soname = "$linkname$sosuffix";
4034 dpurdie 703
 
373 dpurdie 704
    my $shared_path = "\$(LIBDIR)/${shared}";
705
    my $dbg_path =  $shared_path . '.dbg';
227 dpurdie 706
 
707
#.. Cleanup rules
708
#
709
#   map     Map file
710
#   ln      Link from LIBDIR to BINDIR
711
#
261 dpurdie 712
    ToolsetGenerate( "\$(LIBDIR)/${name}.map" );
713
    ToolsetGenerate( "\$(LIBDIR)/${shared}" );
339 dpurdie 714
    ToolsetGenerate( "\$(BINDIR)/${soname}" );
373 dpurdie 715
    ToolsetGenerate( $dbg_path );
227 dpurdie 716
 
717
#.. Build rules
718
#
719
#   name        Base name
720
#   shared      Library name, includes GBE_TYPE specification
721
#
722
    my ($io) = ToolsetPrinter::New();
335 dpurdie 723
    my $dep = $io->SetShldTarget($shared);
227 dpurdie 724
 
725
    $io->Label( "Shared library", $name );
339 dpurdie 726
    PackageShlibAddFiles( $name, "\$(LIBDIR)/$shared" );
373 dpurdie 727
    PackageShlibAddFiles( $name, $dbg_path );
4034 dpurdie 728
 
227 dpurdie 729
    $io->Prt( "\$(LIBDIR)/${shared}:\tSHBASE=${name}\n" );
339 dpurdie 730
    $io->Prt( "\$(LIBDIR)/${shared}:\tSHNAME=${soname}\n" );
731
    $io->Prt( "\$(LIBDIR)/${shared}: \\\n\t\t${dep}" );
321 dpurdie 732
    $io->Entry( "", "", " \\\n\t\t", ".$::o", @$pObjs );
227 dpurdie 733
    $io->Prt( "\\\n\t\t$def" ) if($def);
373 dpurdie 734
    $io->Prt( "\n\t\$(SHLD)" );
735
    $io->Prt( "\n\t\$(call LDSTRIP,$shared_path,$dbg_path)\n\n" );
321 dpurdie 736
 
339 dpurdie 737
#
738
#   Create soft links
739
#       'Real Name' to its 'Link Name'
740
#       'Real Name' to 'SoName' in the BINDIR (for testing I think)
741
#       'Real Name' to 'SoName' in the LIBDIR (if different)
742
#
4034 dpurdie 743
    if ( $shared ne $linkname)
744
    {
745
        $io->Label( "Shared library Symbolic Links", $name );
746
        PackageShlibAddFiles( $name, "\$(LIBDIR)/$linkname" );
747
        $io->Prt( "\$(LIBDIR)/$linkname:\t\\\n" .
748
                  "\t\t\$(GBE_BINDIR)\\\n" .
749
                  "\t\t\$(LIBDIR)/${shared}\n" .
750
                  "\t\$(AA_PRE)(rm -f \$@; ln -s ./$shared \$@)\n\n" );
751
    }
752
 
753
    $io->Label( "Shared library BINDIR Symbolic Links", $name );
754
    PackageShlibAddFiles( $name, "\$(BINDIR)/$soname" );
755
    $io->Prt( "\$(BINDIR)/$soname:\t\\\n" .
339 dpurdie 756
              "\t\t\$(GBE_BINDIR)\\\n" .
757
              "\t\t\$(LIBDIR)/${shared}\n" .
4034 dpurdie 758
              "\t\$(AA_PRE)(rm -f \$@; ln -s ../\$(LIBDIR)/$shared \$@)\n\n" );
339 dpurdie 759
 
4034 dpurdie 760
    if ( $soname ne $shared )
339 dpurdie 761
    {
762
        $io->Label( "Shared library SoName Symbolic Links", $name );
763
        PackageShlibAddFiles( $name, "\$(LIBDIR)/$soname" );
764
        $io->Prt( "\$(LIBDIR)/$soname:\t\\\n" .
765
                  "\t\t\$(GBE_LIBDIR)\\\n" .
766
                  "\t\t\$(LIBDIR)/${shared}\n" .
767
                  "\t\$(AA_PRE)(rm -f \$@; ln -s ./$shared \$@)\n" );
768
    }
769
 
227 dpurdie 770
#.. Linker command file
771
#
772
#       Now the fun part... piecing together a variable $(name_shld)
773
#       which ends up in the command file.
774
#
339 dpurdie 775
    $io->Newline();
227 dpurdie 776
    $io->SetTag( "${name}_shld" );              # command tag
777
    $io->SetTerm( "\n" );
778
 
779
    $io->Label( "Linker commands", $name );     # label
780
 
781
                                                # object list
782
    $io->ObjList( $name, $pObjs, \&ToolsetObjRecipe );
783
 
784
    ToolsetLibStd( $pLibs );                    # push standard libraries
785
 
786
    $io->Cmd( "-Wl,$def_pref$def" ) if ($def);
787
 
788
    $io->Cmd( "-Wl,--start-group" ) if ($multi_scan);
789
    $io->LibList( $name, $pLibs, \&ToolsetLibRecipe );
790
    $io->Cmd( "-Wl,--end-group" ) if ($multi_scan);
791
 
792
    $io->Newline();
793
 
335 dpurdie 794
    #.. Dependency link,
795
    #   Create a library dependency file
796
    #       Create command file to build applicaton dependency list
797
    #       from the list of dependent libraries
798
    #
799
    #       Create makefile directives to include the dependency
800
    #       list into the makefile.
801
    #
802
    $io->DepRules( $pLibs, \&ToolsetLibRecipe, "\$(LIBDIR)/${shared}" );
339 dpurdie 803
    $io->SHLDDEPEND($name, $soname);
227 dpurdie 804
}
805
 
806
 
807
###############################################################################
271 dpurdie 808
# Function        : ToolsetLD
227 dpurdie 809
#
271 dpurdie 810
# Description     : Takes the user options and builds the rules required to
811
#                   link the program 'name'.
227 dpurdie 812
#
271 dpurdie 813
# Inputs          : $name           - base name of the program
814
#                   $pArgs          - Ref to program arguments
815
#                   $pObjs          - Ref to program objects
816
#                   $pLibs          - Ref to program library list
227 dpurdie 817
#
271 dpurdie 818
# Returns         : Nothing
227 dpurdie 819
#
271 dpurdie 820
# Output:         : Rules and recipes to create a program
821
#                       Create program rules and recipes
822
#                       Create linker input script
823
#                       Create library dependency list
824
#                       Include library dependency information
227 dpurdie 825
#
826
sub ToolsetLD
827
{
828
    my( $name, $pArgs, $pObjs, $pLibs ) = @_;
829
    my $static = $::ScmCompilerOpts{'STATIC_PROGS'};
830
    my $multi_scan;
831
 
832
#.. Parse arguments
833
#
834
    foreach $_ ( @$pArgs )
835
    {
836
        if ( m/^--Static$/ ) {
837
            $static = 1;
838
 
839
        } elsif ( m/^--Shared/ ) {
840
            $static = 0;
841
 
842
        } elsif ( /^--MultiScan/i ) {
843
            $multi_scan = 1;
844
 
845
        } elsif ( /^--NoMultiScan/i ) {
846
            $multi_scan = 0;
847
 
848
        } else {
849
            Message( "LD: unknown option $_ -- ignored\n" );
850
        }
851
    }
852
 
271 dpurdie 853
#.. Names of programs and components
854
#
855
    my $base = "\$(BINDIR)/${name}";
856
    my $full = $base . $::exe;
857
    my $map  = $base . '.map';
858
    my $ld  =  $base . '.ld';
373 dpurdie 859
    my $dbg =  $base . '.dbg';
271 dpurdie 860
 
227 dpurdie 861
#.. Cleanup rules
862
#
271 dpurdie 863
    ToolsetGenerate( $ld );
864
    ToolsetGenerate( $map );
373 dpurdie 865
    ToolsetGenerate( $dbg );
227 dpurdie 866
 
867
#.. Build rules
868
#
869
    my ($io) = ToolsetPrinter::New();
335 dpurdie 870
    my $dep = $io->SetLdTarget( $name );
227 dpurdie 871
 
271 dpurdie 872
    $io->Prt( "$full : $dep " );
873
    $io->Entry( "", "", "\\\n\t", ".$::o ", @$pObjs );
373 dpurdie 874
    $io->Prt( "\n\t\$(LD)" );
875
    $io->Prt( "\n\t\$(call LDSTRIP,$full,$dbg)\n\n" );
227 dpurdie 876
 
271 dpurdie 877
 
227 dpurdie 878
#.. Linker command file
879
#
880
#       Now the fun part... piecing together a variable $(name_ld)
881
#       which ends up in the command file.
882
#
883
    $io->SetTag( "${name}_ld" );                # macro tag
884
    $io->SetTerm( "\n" );
885
 
886
    $io->Label( "Linker commands", $name );     # label
887
 
888
    $io->Cmd( "-static" ) if ($static);         # Link as a static program
889
 
890
                                                # object list
891
    $io->ObjList( $name, $pObjs, \&ToolsetObjRecipe );
892
 
893
    ToolsetLibStd( $pLibs );                    # push standard libraries
894
 
895
                                                # library list
896
    $io->Cmd( "-Wl,--start-group" ) if ($multi_scan);
897
    $io->LibList( $name, $pLibs, \&ToolsetLibRecipe );
898
    $io->Cmd( "-Wl,--end-group" ) if ($multi_scan);
899
 
900
    $io->Newline();
901
 
335 dpurdie 902
    #.. Dependency link,
903
    #   Create a library dependency file
904
    #       Create command file to build applicaton dependency list
905
    #       from the list of dependent libraries
906
    #
907
    #       Create makefile directives to include the dependency
908
    #       list into the makefile.
909
    #
910
    $io->DepRules( $pLibs, \&ToolsetLibRecipe, $base );
911
    $io->LDDEPEND();
271 dpurdie 912
 
913
#.. Package up the program and other artifacts
914
#
915
    PackageProgAddFiles ( $name, $full );
373 dpurdie 916
    PackageProgAddFiles ( $name, $dbg );
271 dpurdie 917
 
227 dpurdie 918
}
919
 
920
 
4700 alewis 921
###############################################################################
922
# Function        : ToolsetPreprocessTests
923
#
924
# Description     : 
925
#
926
# Inputs          : None
927
#
928
# Returns         : Nothing
929
#
930
# Output:         : Rules and recipes to run before unit tests
931
#
932
sub ToolsetPreprocessTests
933
{
934
    my ($io) = ToolsetPrinter::New();
935
    if ( $UseGcov && scalar(keys %::OBJSOURCE) > 0 )
936
    {
937
        my $key;
938
        my $value;
939
        while(($key, $value) = each(%::OBJSOURCE))
940
        {
941
            Verbose("$key ==> $value");
942
            $io->Prt("\t" . '$(XX_PRE)rm -f $(OBJDIR)/' . $key . ".gcda\n");
943
        }
944
        $io->Prt("\t" . '${XX_PRE}lcov'
945
                      . ' --capture'
946
                      . ' --initial'
947
                      . ' --base-directory ' . $::Cwd
948
                      . ' --directory $(OBJDIR)'
949
                      . ' --output-file $(OBJDIR)/lcov-baseline.info' 
950
                      . "\n"); 
951
    }
952
}
953
 
954
 
955
###############################################################################
956
# Function        : ToolsetPostprocessTests
957
#
958
# Description     : 
959
#
960
# Inputs          : None
961
#
962
# Returns         : Nothing
963
#
964
# Output:         : Rules and recipes to run after the unit tests
965
#
966
sub ToolsetPostprocessTests
967
{
968
    my ($io) = ToolsetPrinter::New();
969
    if ( $UseGcov && scalar(keys %::OBJSOURCE) > 0 )
970
    {
971
        my $finaldir='$(LOCALDIR)/lcov/$(GBE_PLATFORM)$(GBE_TYPE)';
972
        my $final=$finaldir . '/lcov-final.info';
973
 
974
        $io->Prt("\t" . '$(eval GCDA_COUNT := $(shell find $(OBJDIR) -name "*.gcda"))' . "\n");
975
 
976
        $io->Prt("\t" . '$(XX_PRE)$(mkdir) -p ' . $finaldir . "\n");
977
        $io->Prt("\t" . '$(XX_PRE)if [ "$(GCDA_COUNT)" = "" ]; then' . " \\\n");
978
        $io->Prt("\t\t" . 'if [ ! -e ' . $final . " ]; then \\\n");
979
        $io->Prt("\t\t\t" . '$(cp) $(OBJDIR)/lcov-baseline.info ' . $final . "; \\\n");
980
        $io->Prt("\t\t" . 'else' . " \\\n");
981
        $io->Prt("\t\t\t" . 'lcov'
982
                          . ' --add-tracefile $(OBJDIR)/lcov-baseline.info'
983
                          . ' --add-tracefile ' . $final
984
                          . ' --output-file $(OBJDIR)/lcov-merge.info'
985
                          . "; \\\n"); 
986
        $io->Prt("\t\t\t" . '$(rm) -f ' . $final . "; \\\n");
987
        $io->Prt("\t\t\t" . '$(mv) $(OBJDIR)/lcov-merge.info ' . $final . "; \\\n");
988
        $io->Prt("\t\t" . 'fi' . "; \\\n");
989
        $io->Prt("\t" . 'else' . " \\\n");
990
        $io->Prt("\t\t" . 'lcov'
991
                        . ' --capture'
992
                        . ' --base-directory ' . $::Cwd
993
                        . ' --directory $(OBJDIR)'
994
                        . ' --output-file $(OBJDIR)/lcov-capture.info' 
995
                        . "; \\\n"); 
996
        $io->Prt("\t\t" . 'if [ ! -e ' . $final . " ]; then \\\n");
997
        $io->Prt("\t\t\t" . 'lcov'
998
                          . ' --add-tracefile $(OBJDIR)/lcov-baseline.info'
999
                          . ' --add-tracefile $(OBJDIR)/lcov-capture.info'
1000
                          . ' --output-file ' .  $final
1001
                          . "; \\\n"); 
1002
        $io->Prt("\t\t" . 'else' . " \\\n");
1003
        $io->Prt("\t\t\t" . 'lcov'
1004
                          . ' --add-tracefile $(OBJDIR)/lcov-baseline.info'
1005
                          . ' --add-tracefile $(OBJDIR)/lcov-capture.info'
1006
                          . ' --add-tracefile ' . $final
1007
                          . ' --output-file $(OBJDIR)/lcov-merge.info'
1008
                          . "; \\\n"); 
1009
        $io->Prt("\t\t\t" . '$(rm) -f ' . $final . "; \\\n");
1010
        $io->Prt("\t\t\t" . '$(mv) $(OBJDIR)/lcov-merge.info ' . $final . "; \\\n");
1011
        $io->Prt("\t\t" . 'fi' . "; \\\n");
1012
        $io->Prt("\t" . 'fi' . " \n");
1013
    }
1014
}
1015
 
1016
 
1017
 
1018
###############################################################################
1019
# Function        : ToolsetCollateTestResults
1020
#
1021
# Description     : 
1022
#
1023
# Inputs          : None
1024
#
1025
# Returns         : Nothing
1026
#
1027
# Output:         : Rules and recipes to run after unit test result 
1028
#                   postprocessing.
1029
#
1030
sub ToolsetCollateTestResults
1031
{
1032
    my ($io) = ToolsetPrinter::New();
1033
    if ( $UseGcov && scalar(keys %::OBJSOURCE) > 0 )
1034
    {
1035
        my $finaldir='$(LOCALDIR)/lcov/$(GBE_PLATFORM)$(GBE_TYPE)';
1036
        my $final=$finaldir . '/lcov-final.info';
1037
 
1038
        my $reportdir='$(PKGDIR)/lcov/$(GBE_PLATFORM)$(GBE_TYPE)';
1039
        my $reportindex=$reportdir . '/index.html';
1040
 
1041
        $io->Prt('collate_test_results: ' . $reportindex . "\n");
1042
        $io->Prt($reportindex . ': ' . $final . "\n");
1043
        $io->Prt("\t" . 'genhtml'
1044
                      . ' --frames'
1045
                      . ' --show-details'
1046
                      . ' --output-directory ' . $reportdir
1047
                      . ' --legend'
1048
                      . ' --demangle-cpp'
1049
                      . ' ' . $final
1050
                      . "\n");
1051
    }
1052
}
1053
 
227 dpurdie 1054
########################################################################
1055
#
1056
#   Push standard "system" libraries. This is a helper function
1057
#   used within this toolset.
1058
#
1059
#   Arguments:
1060
#       $plib       Reference to library array.
1061
#
1062
########################################################################
1063
 
1064
sub ToolsetLibStd
1065
{
1066
}
1067
 
1068
 
1069
########################################################################
1070
#
1071
#   Generate a linker object recipe.  This is a helper function used 
1072
#   within this toolset.
1073
#
1074
#   Arguments:
1075
#       $io         I/O stream
1076
#
1077
#       $target     Name of the target
1078
#
1079
#       $obj        Library specification
1080
#
1081
########################################################################
1082
 
1083
sub ToolsetObjRecipe
1084
{
1085
    my ($io, $target, $obj) = @_;
1086
 
1087
    $io->Cmd( "\$(strip $obj).$::o" );
1088
}
1089
 
1090
 
1091
###############################################################################
1092
#
1093
#   Parse a linker lib list
1094
#   This is a helper function used within this toolset
1095
#
1096
#   Arguments:
1097
#       $target     Name of the target
1098
#
1099
#       $lib        Library specification
1100
#
1101
#       $tag        Tag (user specified)
1102
#
1103
#       $dp         If building a depend list, the full target name.
1104
#
1105
###############################################################################
1106
 
1107
sub ToolsetLibRecipe
1108
{
1109
    my ($io, $target, $lib, $dp) = @_;
1110
 
1111
    if ( ! defined($dp) ) {                     # linker
1112
        $lib =~ s/^lib//;                       # .. remove leading 'lib'
1113
        $io->Cmd( "-l$lib" );
1114
 
1115
    } else {                                    # depend
1116
        $io->Cmd( "$dp:\t@(vlib2,$lib,GCC_LIB)" );
1117
 
1118
    }
1119
}
1120
 
1121
#.. Successful termination
1122
1;
1123