Subversion Repositories DevTools

Rev

Rev 6459 | Rev 6898 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
6198 dpurdie 1
########################################################################
2
# COPYRIGHT - VIX IP PTY LTD ("VIX"). ALL RIGHTS RESERVED.
227 dpurdie 3
#
6198 dpurdie 4
# Module name   : GCC.PL
5
# Module type   : JATS Utility
6
# Compiler(s)   : Perl
7
# Environment(s): jats
227 dpurdie 8
#
6198 dpurdie 9
# Description   : GCC C/C++ toolset
227 dpurdie 10
#
6198 dpurdie 11
#......................................................................#
227 dpurdie 12
 
13
use strict;
14
use warnings;
15
 
4728 dpurdie 16
# Global variables
4034 dpurdie 17
our $ScmPlatform;
18
our $ScmNoToolsTest;
19
 
4728 dpurdie 20
#   Misc variables
21
my $UseGcov = 0;
4835 dpurdie 22
my $LcovExplicitBranch = '';
4728 dpurdie 23
my $UseCppcheck = 0;
5744 dpurdie 24
my $GCCRPath;
6198 dpurdie 25
my @ldFixups;
4728 dpurdie 26
 
227 dpurdie 27
##############################################################################
28
#   Configuration information
29
#   Cross reference from CrossCompiler Alias to actual paths
30
#   Structure:
31
#   Hash reference: Array of toolchain information
369 dpurdie 32
#       Mandatory
33
#          ROOT             => Root of compiler
34
#          BASE             => Base for binaries
35
#       Optional
36
#          CC_OPTS          => Additonal Compiler options
4034 dpurdie 37
#          CC_OPTSP         => Production Compiler options
38
#          CC_OPTSD         => Debug Compiler options
5744 dpurdie 39
#          CXX_OPTS         => Additional C++ Options
6459 dpurdie 40
#          LDFLAGS          => Linker flags
369 dpurdie 41
#          UNCONTROLLED     => Boolean to create warning
6459 dpurdie 42
#          DEPRECATED       => Boolean to create warning
43
#          DISCONTINUED     => Boolean to create error and not build anything
3967 dpurdie 44
#          PACKAGE_ARCH     => Packageing architecture
45
#          VERSION          => Version reported by GCC
46
#          MACHINE          => Machine reported by GCC
5796 dpurdie 47
#          RPATH            => Relative Path to compiler installed runtime
48
#                              Absolute or Relative
4034 dpurdie 49
#          COMPILER_OPTIONS => Toolset specific compiler initial options
50
#                              This is a comma seperated list
227 dpurdie 51
my %ToolsetConfig = (
52
 
369 dpurdie 53
    'i386-unknown-linux-gnu'    => {
5708 dpurdie 54
        ROOT        => '/opt/crosstool/gcc-4.1.1-glibc-2.5/i586-unknown-linux-gnu',
55
        BASE        => 'bin/i586-unknown-linux-gnu-',
3967 dpurdie 56
       VERSION      => '4.1.1',
57
       MACHINE      => 'i586-unknown-linux-gnu'
369 dpurdie 58
    },
227 dpurdie 59
 
369 dpurdie 60
    'arm-9tdmi-linux-gnu'       => {
5708 dpurdie 61
        ROOT        => '/opt/crosstool/gcc-4.1.1-glibc-2.5/arm-9tdmi-linux-gnu',
62
        BASE        => 'bin/arm-9tdmi-linux-gnu-',
63
        VERSION     => '4.1.1',
64
        MACHINE     => 'arm-9tdmi-linux-gnu'
369 dpurdie 65
        },
247 dpurdie 66
 
369 dpurdie 67
    'powerpc-603e-linux-gnu'    => {
5708 dpurdie 68
       ROOT         => '/opt/crosstool/gcc-4.1.1-glibc-2.5/powerpc-603e-linux-gnu',
69
       BASE         => 'bin/powerpc-603e-linux-gnu-',
3967 dpurdie 70
       VERSION      => '4.1.1',
71
       MACHINE      => 'powerpc-603e-linux-gnu'
369 dpurdie 72
    },
337 dpurdie 73
 
369 dpurdie 74
    'arm-926ejs-linux-gnueabi'  => {
5708 dpurdie 75
       ROOT         => '/opt/crosstool/gcc-4.4.3-glibc-2.9/arm-926ejs-linux-gnueabi',
76
       BASE         => 'bin/arm-926ejs-linux-gnueabi-',
77
       CC_OPTS      => '-Wno-psabi',
3967 dpurdie 78
       VERSION      => '4.4.3',
79
       MACHINE      => 'arm-926ejs-linux-gnueabi'
369 dpurdie 80
    },
81
 
5708 dpurdie 82
    'arm-926ejs-linux-gnueabi-v2'  => {
83
       ROOT         => '/opt/crosstool/gcc-5.2.0-glibc-2.17/arm-926ejs-linux-gnueabi',
84
       BASE         => 'bin/arm-926ejs-linux-gnueabi-',
85
       CC_OPTS      => '-Wno-psabi',
5736 dpurdie 86
       CXX_OPTS     => '-std=gnu++11',
5708 dpurdie 87
       VERSION      => '5.2.0',
88
       MACHINE      => 'arm-926ejs-linux-gnueabi'
89
    },
90
 
91
    'powerpc-603e-linux-gnu-v2'  => {
92
       ROOT         => '/opt/crosstool/gcc-5.2.0-glibc-2.17/powerpc-603e-linux-gnu',
93
       BASE         => 'bin/powerpc-603e-linux-gnu-',
5736 dpurdie 94
       CXX_OPTS     => '-std=gnu++11',
5708 dpurdie 95
       VERSION      => '5.2.0',
96
       MACHINE      => 'powerpc-603e-linux-gnu'
97
    },
98
 
3967 dpurdie 99
    'i686-linux-gnu'    => {
100
       ROOT         => '/usr',
101
       BASE         => 'bin/',
102
       PACKAGE_ARCH => 'i386',
103
       VERSION      => '4.6',
104
       MACHINE      => 'i686-linux-gnu'
105
    },
106
 
5716 dpurdie 107
    'i686-vix_ubuntu12_c11-linux-gnu'    => {
108
       ROOT         => '/opt/crosstool/gcc-5.2.0-glibc-2.17/i686-vix_ubuntu12_c11-linux-gnu',
109
       BASE         => 'bin/i686-vix_ubuntu12_c11-linux-gnu-',
110
       PACKAGE_ARCH => 'i386',
5736 dpurdie 111
       CXX_OPTS     => '-std=gnu++11',
5716 dpurdie 112
       VERSION      => '5.2.0',
5744 dpurdie 113
       MACHINE      => 'i686-vix_ubuntu12_c11-linux-gnu',
5796 dpurdie 114
       RPATH        => '/lib/i686-vix_ubuntu12_c11-linux-gnu',
5716 dpurdie 115
    },
116
 
4109 dpurdie 117
    'arm-iwmmxt-linux-gnueabi'  => {
5708 dpurdie 118
       ROOT         => '/opt/marvel',
119
       BASE         => 'bin/arm-iwmmxt-linux-gnueabi-',
4109 dpurdie 120
       VERSION      => '4.2.4',
121
       MACHINE      => 'arm-iwmmxt-linux-gnueabi'
122
    },
123
 
5619 dpurdie 124
    'arm-unknown-linux-gnueabi-sk20-4.1.1.0'  => {
5708 dpurdie 125
       ROOT         => '/opt/arm-unknown-linux-gnueabi-sk20-4.1.1.0',
126
       BASE         => 'bin/arm-unknown-linux-gnueabi-',
5330 dpurdie 127
       VERSION      => '4.8.2',
128
       MACHINE      => 'arm-unknown-linux-gnueabi'
129
    },
130
 
6198 dpurdie 131
    'gmx-sdk-imx6-toolchain-5.0.0.0'  => {
132
       ROOT         => '/opt/gmx-sdk-imx6-toolchain-5.0.0.0',
133
       BASE         => 'bin/arm-unknown-linux-gnueabi-',
134
       VERSION      => '4.9.1',
135
       MACHINE      => 'arm-unknown-linux-gnueabi',
136
       COMPILER_OPTIONS =>  'pic,brokenldscripts',
137
    },
138
 
6276 dpurdie 139
    # Ubuntu14
4814 dpurdie 140
    'x86_64-linux-gnu'    => {
141
       ROOT         => '/usr',
142
       BASE         => 'bin/',
143
       PACKAGE_ARCH => 'amd64',
6276 dpurdie 144
       CXX_OPTS     => '-std=gnu++11',
4814 dpurdie 145
       VERSION      => '4.8',
4928 dpurdie 146
       MACHINE      => 'x86_64-linux-gnu',
5115 dpurdie 147
       COMPILER_OPTIONS =>  'pic'               # Always create PIC
4814 dpurdie 148
    },
4109 dpurdie 149
 
6276 dpurdie 150
    # Ubuntu16
6133 dpurdie 151
    'x86_64-linux-gnu-5.4'    => {
152
       ROOT         => '/usr',
153
       BASE         => 'bin/',
154
       PACKAGE_ARCH => 'amd64',
6276 dpurdie 155
       CXX_OPTS     => '-std=gnu++11',
6133 dpurdie 156
       VERSION      => '5.4.0',
157
       MACHINE      => 'x86_64-linux-gnu',
158
       COMPILER_OPTIONS =>  'pic'               # Always create PIC
159
    },
160
 
161
    'x86_64-redhat-linux-4.8.5' => {
162
        ROOT         => '/usr',
163
        BASE         => 'bin/',
6177 dpurdie 164
        PACKAGE_ARCH => 'x86_64',
6276 dpurdie 165
        CXX_OPTS     => '-std=gnu++11',
6133 dpurdie 166
        VERSION      => '4.8.5',
167
        MACHINE      => 'x86_64-redhat-linux',
168
        COMPILER_OPTIONS =>  'pic'               # Always create PIC
169
        },
170
 
6798 dpurdie 171
    # STIB Parkeon
172
    'arm-linux-gnueabi-4.6.3' => {
173
        ROOT         => '/opt/parkeon-arm-linux-gnueabi-4.6',
174
        BASE         => 'bin/arm-linux-gnueabi-',
175
        PACKAGE_ARCH => 'armel',
176
        #CXX_OPTS     => '',
177
        VERSION      => '4.6.3',
178
        MACHINE      => 'arm-linux-gnueabi',
179
        COMPILER_OPTIONS =>  'pic'               # Always create PIC
180
        },
181
 
182
 
227 dpurdie 183
    #
184
    #   Old (not to be used) version of the embedded toolchain
4003 dpurdie 185
    #   This was deprecated in favor of gcc-4.1.1-glibc-2.5
227 dpurdie 186
    #   It is not possible to reproduce old packages using the old compiler
187
    #   This is a known issue
188
    #
369 dpurdie 189
    'i386-unknown-linux-gnu.glibc-2.3.2' => {
5708 dpurdie 190
       ROOT         => '/opt/crosstool/gcc-4.1.0-glibc-2.3.2/i386-unknown-linux-gnu',
191
       BASE         => 'bin/i386-unknown-linux-gnu-'
369 dpurdie 192
    },
227 dpurdie 193
 
369 dpurdie 194
    'arm-9tdmi-linux-gnu.glibc-2.3.2' => {
5708 dpurdie 195
       ROOT         => '/opt/crosstool/gcc-4.1.0-glibc-2.3.2/arm-9tdmi-linux-gnu',
196
       BASE         => 'bin/arm-9tdmi-linux-gnu-'
369 dpurdie 197
    },
227 dpurdie 198
 
199
    #
200
    #   Not too sure where this is used
201
    #
369 dpurdie 202
    'armv4l-unknown-linux-gcc' => {
5708 dpurdie 203
       ROOT         => '/opt/host/armv4l',
204
       BASE         => 'bin/armv4l-unknown-linux-'
369 dpurdie 205
    },
227 dpurdie 206
 
207
    #
208
    #   The compiler for the current local machine
209
    #
369 dpurdie 210
    'i386-unknown-linux-gcc' => {
5708 dpurdie 211
       ROOT         => '/usr',
212
       BASE         => 'bin/',
369 dpurdie 213
       UNCONTROLLED => 1,
3967 dpurdie 214
       PACKAGE_ARCH => 'i386',
369 dpurdie 215
    },
216
);
227 dpurdie 217
 
218
#
219
#   Cross reference from GCCTarget to GBE_MACHTYPE for which it can
220
#   build using the 'native gcc'. This is NOT the preferred mode of operation
221
#   as the compiler is not as controlled as the cross compilers.
222
#
223
my %NativeCompilers = (
224
    'Linux i386'       => 'linux_i386',
225
    );
226
 
227
##############################################################################
228
#   ToolsetInit()
229
#       Runtime initialisation
230
#
231
##############################################################################
232
 
233
ToolsetInit();
234
 
235
sub ToolsetInit
236
{
5731 dpurdie 237
    my( $GCCTarget, $GCCToolchain, $GCCRoot, $GCCBin, $GCCAr, $GCCObjCopy, $GCCGcovTool );
4728 dpurdie 238
    my( $GCCFlags,  $GCCFlagsP, $GCCFlagsD, $LDFlags );
5726 dpurdie 239
    my( $GCCXXFlags );
3967 dpurdie 240
    my( $PkgArch);
4034 dpurdie 241
    my( $arg_alias, $tools_found, $compiler_tool );
227 dpurdie 242
 
243
#.. Toolset configuration
6798 dpurdie 244
#   Also $::ScmToolsetProperties{}
227 dpurdie 245
#
246
    $::ScmToolsetVersion = "1.0.0";             # our version
247
    $::ScmToolsetGenerate = 0;                  # GEN generate optional
248
    $::ScmToolsetCompilerPath = 1;              # Exports Compiler path to makefile via SCM_COMPILERPATH
271 dpurdie 249
    $::ScmToolsetProgDependancies = 0;          # handle Prog dependancies myself
339 dpurdie 250
    $::ScmToolsetSoName = 1;                    # Shared library supports SoName
227 dpurdie 251
 
252
#.. Standard.rul requirements
253
#
254
    $::s = "asm";
255
    $::o = "o";
256
    $::so = "so";
257
    $::a = "a";
258
    $::exe = "";
259
 
260
#.. Parse arguments
261
#
262
    foreach $_ ( @::ScmToolsetArgs ) {
263
        if (/^--Target=(.*)/) {                 # OS Version
264
            $GCCTarget = "$1";
265
 
266
        } elsif (/^--CrossAlias=(.*)/) {        # CrossCompiler target-alias
267
            $arg_alias = $1;
268
 
4728 dpurdie 269
        } elsif (/^--UseGcov/) {                # Compile for code coverage
270
            $UseGcov = 1;
271
 
4835 dpurdie 272
        } elsif (/^--LcovExplicitBranch/) {     # Version of lcov requires explicit branch coverage
273
            $LcovExplicitBranch = ' --rc lcov_branch_coverage=1';
274
 
4728 dpurdie 275
        } elsif (/^--UseCppcheck/) {            # Use cppcheck as the lint tool
276
            $UseCppcheck = 1;
277
 
4034 dpurdie 278
        } elsif (/^--CompilerTool=(.*)/) {      # CrossCompiler located in package
279
            $compiler_tool = $1;
280
 
227 dpurdie 281
        } else {
282
            Message( "gcc toolset: unknown option $_ -- ignored\n" );
283
        }
284
    }
285
 
286
    foreach $_ ( @::ScmPlatformArgs ) {
287
        if (/^--product=(.*)/) {                # GBE product
288
 
289
        } else {
290
            Message( "gcc toolset: unknown platform argument $_ -- ignored\n" );
291
        }
292
    }
293
 
294
    Error ("TOOLSET/gcc - Target undefined" )
295
        unless ($GCCTarget);
296
 
4034 dpurdie 297
    #
298
    #   If the toolset is not required, then do not process any futher
299
    #   We may not find the compiler
300
    #
301
    return
302
        if ($ScmNoToolsTest);
303
 
227 dpurdie 304
#.. Cross compile support
4034 dpurdie 305
#   Compiler provided in package, rather than install on machine
227 dpurdie 306
#
4034 dpurdie 307
if ( $compiler_tool  )
308
{
309
    #
310
    #   The GCC toolset will handle a compiler provided within a package
311
    #   Initial requirement was for ANDROID NDKs where the compiler is
312
    #   a part of the NDK and will change.
313
    #
314
    #   Compilers in packages will have a file in gbe/COMPILERS/<compiler_tool>
315
    #   that contains data specifically designed for this toolset
316
    #
317
    Verbose("Locate compiler in package: $compiler_tool");
318
    my @toolList;
319
    my $toolPath;
320
    my $toolPkg;
321
    for my $entry (@{$::ScmBuildPkgRules{$ScmPlatform} })
322
    {
323
        my $tpath = join('/', $entry->{ROOT}, 'gbe', 'COMPILERS' , $compiler_tool);
324
        if ( -f $tpath  )
325
        {
326
            push @toolList, $entry->{NAME};
327
            $toolPath = $tpath;
328
            $toolPkg = $entry;
329
        }
330
    }
331
    Error ("Multiple packages provide required compiler:", @toolList)
332
        if ( scalar(@toolList) > 1 );
333
    Error ("Required compiler not found in any package", "Compiler: $compiler_tool")
334
        unless ( scalar(@toolList) == 1 );
335
 
336
    #
337
    #   Process the compiler info file
338
    #   Rip out the data and create a hash of item/values
339
    #   File format:
340
    #       '#' is a line comment
341
    #       item=value
342
    #
343
    my %data;
344
    open (my $DATA, '<', $toolPath ) || Error("Cannot open compiler datafile. $!", "File: $toolPath");
345
    while ( <$DATA> )
346
    {
347
        $_ =~ s~\s+$~~;
348
        next if ( m~^#~ );
349
        m~(.*?)\s*=\s*(.*)~;
350
        $data{$1} = $2;
351
    }
352
    close $DATA;
353
 
354
    #
355
    #   Force this compilers data into the ToolsetConfig hash
356
    #
357
    $arg_alias = $compiler_tool;
358
    %ToolsetConfig = ();
359
 
360
    $ToolsetConfig{$arg_alias}{ROOT} = join('/', $toolPkg->{ROOT}, $data{ROOT} );
361
    $ToolsetConfig{$arg_alias}{BASE} = $data{BASE} . '-';
362
    $ToolsetConfig{$arg_alias}{CC_OPTS} = $data{CFLAGS};
363
    $ToolsetConfig{$arg_alias}{CC_OPTSP} = $data{CFLAGSP};
364
    $ToolsetConfig{$arg_alias}{CC_OPTSD} = $data{CFLAGSD};
5726 dpurdie 365
    $ToolsetConfig{$arg_alias}{CXX_OPTS} = $data{CXXFLAGS};
6459 dpurdie 366
    $ToolsetConfig{$arg_alias}{LDFLAGS} = $data{LDFLAGS};
4034 dpurdie 367
    $ToolsetConfig{$arg_alias}{VERSION} = $data{VERSION};
368
    $ToolsetConfig{$arg_alias}{MACHINE} = $data{MACHINE};
369
    $ToolsetConfig{$arg_alias}{COMPILER_OPTIONS} = $data{COMPILER_OPTIONS};
5744 dpurdie 370
    $ToolsetConfig{$arg_alias}{RAPTH} = $data{RPATH};
6459 dpurdie 371
    $ToolsetConfig{$arg_alias}{DEPRECATED} = $data{DEPRECATED};
372
    $ToolsetConfig{$arg_alias}{DISCONTINUED} = $data{DISCONTINUED};
4034 dpurdie 373
}
374
 
375
#.. Cross compile support
376
#
227 dpurdie 377
#   Toolchain=root,[bin]
378
#
379
    if ( $arg_alias )
380
    {
381
        if ( exists $ToolsetConfig{ $arg_alias } )
382
        {
369 dpurdie 383
            $GCCToolchain = $ToolsetConfig{ $arg_alias };
5330 dpurdie 384
            my $testCompilerPath = $GCCToolchain->{ROOT} . '/' . $GCCToolchain->{BASE} . 'gcc';
385
            $tools_found = (-d $GCCToolchain->{ROOT}) && ( -f $testCompilerPath);
227 dpurdie 386
            Warning ("gcc toolset: CrossPlatform toolchain not found for: $arg_alias",
5708 dpurdie 387
                     "Path    : $GCCToolchain->{ROOT}" ,
388
                     "Compiler: $testCompilerPath " 
5330 dpurdie 389
                      ) unless $tools_found;
227 dpurdie 390
        }
391
        else
392
        {
393
            Error("gcc toolset: CrossPlatform Alias not configured: $arg_alias");
394
        }
369 dpurdie 395
 
396
        Warning ("Uncontrolled toolchain used: $arg_alias")
397
            if ( exists($GCCToolchain->{UNCONTROLLED}) && $GCCToolchain->{UNCONTROLLED} );
6459 dpurdie 398
 
399
        Warning ("Deprecated toolchain used: $arg_alias")
400
            if ( exists($GCCToolchain->{DEPRECATED}) && $GCCToolchain->{DEPRECATED} );
401
 
402
        Error ("Discontinued toolchain used: $arg_alias")
403
            if ( exists($GCCToolchain->{DISCONTINUED}) && $GCCToolchain->{DISCONTINUED} );
227 dpurdie 404
    }
405
 
406
    #
407
    #   If no Cross compiler toolchain is found (preferred method), then attempt
408
    #   to match a native compiler. Only known targets allow a native build
409
    #
410
    unless ( $tools_found )
411
    {
412
        if ( exists ( $NativeCompilers{$GCCTarget} ))
413
        {
414
            if ( $NativeCompilers{$GCCTarget} eq $::GBE_MACHTYPE )
415
            {
416
                $tools_found = 1;
369 dpurdie 417
                $GCCToolchain = undef;
227 dpurdie 418
            }
419
        }
420
    }
421
 
422
    #
423
    #   Must have a toolset by now, either a cross compiler or Native
424
    #
425
    Error ("gcc toolset: Toolchain not found for: $GCCTarget" )
426
        unless ( $tools_found );
427
 
428
 
369 dpurdie 429
    if ( defined $GCCToolchain )
227 dpurdie 430
    {
431
        #
369 dpurdie 432
        #   Parse GCCToolchain. Potential parts to create
433
        #       GCCRoot     - Location to find the effective /usr/include directory
434
        #       GCCBin      - Path to the gcc executable
435
        #       GCCAr       - Path to the ar executable
4034 dpurdie 436
        #       GCCFlags    - Additional compiler flags. Also Production and Debug
227 dpurdie 437
        #
369 dpurdie 438
        $GCCRoot = $GCCToolchain->{ROOT};
439
        $GCCBin = '${GCC_ROOT}/' . $GCCToolchain->{BASE} . 'gcc';
440
        $GCCAr =  '${GCC_ROOT}/' . $GCCToolchain->{BASE} . 'ar';
5731 dpurdie 441
        $GCCGcovTool = '${GCC_ROOT}/' . $GCCToolchain->{BASE} . 'gcov';
373 dpurdie 442
        $GCCObjCopy =  '${GCC_ROOT}/' . $GCCToolchain->{BASE} . 'objcopy';
5796 dpurdie 443
        if (exists $GCCToolchain->{RPATH}) {
444
            if( $GCCToolchain->{RPATH} =~ m~^/~ ) {
445
                $GCCRPath = $GCCToolchain->{RPATH}; 
446
            } else {
447
                $GCCRPath = '${GCC_ROOT}/' . $GCCToolchain->{RPATH};
448
            }
449
        }
369 dpurdie 450
        $GCCFlags = $GCCToolchain->{CC_OPTS};
4034 dpurdie 451
        $GCCFlagsP = $GCCToolchain->{CC_OPTSP};
452
        $GCCFlagsD = $GCCToolchain->{CC_OPTSD};
5726 dpurdie 453
        $GCCXXFlags = $GCCToolchain->{CXX_OPTS};
6459 dpurdie 454
        $LDFlags = $GCCToolchain->{LDFLAGS} if defined($GCCToolchain->{LDFLAGS});
3967 dpurdie 455
        $PkgArch = $GCCToolchain->{PACKAGE_ARCH};
6177 dpurdie 456
        SetGlobalOption('PACKAGE_ARCH', $PkgArch) if defined $PkgArch;
227 dpurdie 457
    }
458
    else
459
    {
373 dpurdie 460
        $GCCRoot = '/usr';
461
        $GCCBin = 'gcc';
462
        $GCCAr = 'ar';
463
        $GCCObjCopy =  'objcopy';
227 dpurdie 464
    }
4728 dpurdie 465
 
466
    #
467
    #   When running under gcov we need to instruct GCC to perform code coverage
468
    #   generation in both C flags and LD flags
469
    #
470
    if ( $UseGcov )
471
    {
472
        $GCCFlags .= ' -coverage';
473
        $LDFlags  .= ' -coverage';
474
    }
475
 
476
    #
477
    #   When running with cppcheck we need to include it in our environment
478
    #
479
    if ( $UseCppcheck )
480
    {
481
        ToolsetRequire( "cppcheck" );
482
        PlatformDefine( "CPPCHECK_PLATFORM := unix32" );
483
    }
484
 
227 dpurdie 485
 
486
#.. Define GCC environment
487
#
488
    PlatformDefine( "
489
#################################################
490
# GCC toolchain definitions 
491
#
492
#..");
369 dpurdie 493
    PlatformDefine( "GCC_TARGET         := $GCCTarget" );
494
    PlatformDefine( "GCC_ROOT           := $GCCRoot" );
495
    PlatformDefine( "GCC_CC             := $GCCBin" );
496
    PlatformDefine( "GCC_AR             := $GCCAr" );
373 dpurdie 497
    PlatformDefine( "GCC_OBJCOPY        := $GCCObjCopy" );
5731 dpurdie 498
    PlatformDefine( "GCC_GCOVTOOL       := $GCCGcovTool" );
369 dpurdie 499
    PlatformDefine( "GCC_CFLAGS         := $GCCFlags" ) if defined $GCCFlags;
4034 dpurdie 500
    PlatformDefine( "GCC_CFLAGSP        := $GCCFlagsP" ) if defined $GCCFlagsP;
501
    PlatformDefine( "GCC_CFLAGSD        := $GCCFlagsD" ) if defined $GCCFlagsD;
4728 dpurdie 502
    PlatformDefine( "GCC_LDFLAGS        := $LDFlags" ) if defined $LDFlags;
5726 dpurdie 503
    PlatformDefine( "GCC_CXXFLAGS       := $GCCXXFlags" ) if defined $GCCXXFlags;
369 dpurdie 504
 
5726 dpurdie 505
 
227 dpurdie 506
    #
507
    #   Required since this toolset advertises: ScmToolsetCompilerPath
508
    #
369 dpurdie 509
    PlatformDefine( "SCM_COMPILERPATH   := \$\{GCC_CC\}" );
3967 dpurdie 510
 
511
    #
512
    #   Sanity checking
513
    #
514
    PlatformDefine( "GCC_EVERSION       := " . $GCCToolchain->{VERSION} ) if defined $GCCToolchain->{VERSION};
515
    PlatformDefine( "GCC_EMACHINE       := " . $GCCToolchain->{MACHINE} ) if defined $GCCToolchain->{MACHINE};
516
 
517
    #
518
    #   Option indication of packaging architecture
519
    #   Used by non-embedded systems for packaging. See debian_packager
520
    #
521
    PlatformDefine( "PACKAGE_ARCH       := $PkgArch" ) if (defined $PkgArch);
369 dpurdie 522
    PlatformDefine( "" );
227 dpurdie 523
 
524
#.. Piece the world together
525
#
3967 dpurdie 526
    Init( 'gcc' );
227 dpurdie 527
    ToolsetDefines( "gcc.def" );
528
    ToolsetRules( "gcc.rul" );
529
    ToolsetRules( "standard.rul" );
530
 
4094 dpurdie 531
 
532
    PlatformDefine( "CTAGS_EXE:= ctags" );
533
    ToolsetRequire( "exctags" );                # and Exuberant Ctags
534
 
227 dpurdie 535
#   Create a standard data structure
536
#   This is a hash of hashes
537
#       The first hash is keyed by CompileOption keyword
538
#       The second hash contains pairs of values to set or remove
539
#
540
    %::ScmToolsetCompilerOptions =
541
    (
542
        #
543
        #   Control the thread model to use
544
        #   This will affect the compiler options and the linker options
545
        #
546
        'staticprogs'        => { 'STATIC_PROGS' , '1' },      # Progams link staticlly
547
        'no_staticprogs'     => { 'STATIC_PROGS' , undef },    # Default
4034 dpurdie 548
        'noversiondll'       => { 'NO_VERSIONED_DLLS', 1 },    # Matches usage elsewhere
5115 dpurdie 549
        'pic'                => { 'GEN_PIC' , '1' },           # Force PIC for static libs
550
        'nopic'              => { 'GEN_PIC' , undef },         # No Pic on Static libs
6198 dpurdie 551
        'brokenldscripts'    => { 'BROKEN_LDSCRIPTS' , 1 },    # the linker is brken and cannot handle linker scripts
227 dpurdie 552
    );
553
 
554
    #
555
    #   Set default options
556
    #
557
    $::ScmCompilerOpts{'STATIC_PROGS'} = undef;
4034 dpurdie 558
    $::ScmCompilerOpts{'NO_VERSIONED_DLLS'} = undef;
559
 
560
    #
561
    #   Process toolset-specfic compiler options
562
    #
563
    if ( exists $GCCToolchain->{COMPILER_OPTIONS} )
564
    {
565
        CompileOptions('*', split(',',$GCCToolchain->{COMPILER_OPTIONS}) );
566
    }
227 dpurdie 567
}
568
 
4094 dpurdie 569
###############################################################################
570
#   ToolsetCTAGS()
571
#       This subroutine takes the user options and builds the rules
572
#       required to build the CTAGS database.
573
#
574
#   Arguments:
575
#       --xxx                   No arguments currently defined
576
#
577
#   Output:
578
#       [ctags:]
579
#           $(EXCTAGS)
580
#
581
###############################################################################
227 dpurdie 582
 
4094 dpurdie 583
sub ToolsetCTAGS
584
{
585
    EXCTAGS( @_ );
586
}
587
 
588
 
227 dpurdie 589
###############################################################################
590
#   ToolsetCC( $source, $obj, \@args )
591
#       This subroutine takes the user options and builds the rule(s)
592
#       required to compile the source file 'source' to 'obj'
593
#
594
###############################################################################
595
 
596
sub ToolsetCC
597
{
598
    my( $source, $obj, $pArgs ) = @_;
599
    my( $cflags, $file ) = "";
600
 
601
    foreach $_ ( @$pArgs ) {
602
        if (/--Shared$/) {                      # Building a 'shared' object
603
            $cflags  = "$cflags \$(SHCFLAGS)";
604
        } else {
605
            Message( "CC: unknown option $_ -- ignored\n" );
606
        }
607
    }
608
 
609
    MakePrint( "\n\t\$(CC)\n" );
610
    if ( $cflags )
611
    {                                           # object specific CFLAGS
612
        MakePadded( 4, "\$(OBJDIR)/$obj.$::o:" );
613
        MakePrint( "\tCFLAGS +=$cflags\n" );
614
    }
615
 
616
    $file = StripExt( $obj );                   # Metric working file
617
    ToolsetGenerate( "\$(OBJDIR)/$file.met" );
4728 dpurdie 618
 
619
    if ( $UseGcov )
620
    {
621
        ToolsetGenerate( '$(OBJDIR)/' . $file . '.gcno' );
622
        ToolsetGenerate( '$(OBJDIR)/' . $file . '.gcda' );
623
    }
227 dpurdie 624
}
625
 
626
 
627
###############################################################################
628
#   ToolsetCCDepend( $depend, \@sources )
629
#       This subroutine takes the user options and builds the
630
#       rule(s) required to build the dependencies for the source
631
#       files 'sources' to 'depend'.
632
#
633
###############################################################################
634
 
635
sub ToolsetCCDepend
636
{
637
    MakePrint( "\t\$(CCDEPEND)\n" );
638
}
639
 
640
 
641
###############################################################################
642
#   ToolsetCXX( $source, $obj, \@args )
643
#       This subroutine takes the user options and builds the rule(s)
644
#       required to compile the source file 'source' to 'obj'
645
#
646
###############################################################################
647
 
648
sub ToolsetCXX
649
{
650
    my( $source, $obj, $pArgs ) = @_;
651
    my( $cflags, $file ) = "";
652
 
653
    foreach $_ ( @$pArgs ) {
654
        if (/--Shared$/) {                      # Building a 'shared' object
655
            $cflags  = "$cflags \$(SHCXXFLAGS)";
656
        } else {
657
            Message( "CXX: unknown option $_ -- ignored\n" );
658
        }
659
    }
660
 
661
    MakePrint( "\n\t\$(CXX)\n" );
662
    if ( $cflags )
663
    {                                           # object specific CFLAGS
664
        MakePadded( 4, "\$(OBJDIR)/$obj.$::o:" );
665
        MakePrint( "\tCXXFLAGS +=$cflags\n" );
666
    }
667
 
668
    $file = StripExt( $obj );                   # Metric working file
669
    ToolsetGenerate( "\$(OBJDIR)/$file.met" );
4728 dpurdie 670
 
671
    if ( $UseGcov )
672
    {
673
        ToolsetGenerate( '$(OBJDIR)/' . $file . '.gcno' );
674
        ToolsetGenerate( '$(OBJDIR)/' . $file . '.gcda' );
675
    }
227 dpurdie 676
}
677
 
678
 
679
###############################################################################
680
#   ToolsetCXXDepend( $depend, \@sources )
681
#       This subroutine takes the user options and builds the
682
#       rule(s) required to build the dependencies for the source
683
#       files 'sources' to 'depend'.
684
#
685
###############################################################################
686
 
687
sub ToolsetCXXDepend
688
{
287 dpurdie 689
    ToolsetCCDepend();
227 dpurdie 690
}
691
 
692
 
693
###############################################################################
694
#   ToolsetAS( $source, $obj, \@args )
695
#       This subroutine takes the user options and builds the rule(s)
696
#       required to compile the source file 'source' to 'obj'
697
#
698
###############################################################################
699
 
700
sub ToolsetAS
701
{
702
    MakePrint( "\n\t\$(AS)\n" );
703
}
704
 
705
sub ToolsetASDepend
706
{
707
}
708
 
709
 
710
###############################################################################
711
#   ToolsetAR( $name, \@args, \@objs )
712
#       This subroutine takes the user options and builds the rules
713
#       required to build the library 'name'.
714
#
715
#   Arguments:
716
#       n/a
717
#
718
#   Output:
719
#       $(BINDIR)/name$.${a}:   .... ]
720
#           $(AR)
721
#
722
#       name_ld += ...  Linker command file
723
#           :
724
#
725
#       name_dp += ...  Dependency list
726
#           :
727
#
728
###############################################################################
729
 
730
sub ToolsetAR
731
{
732
    my( $name, $pArgs, $pObjs ) = @_;
733
 
734
#.. Parse arguments
735
#
736
    foreach $_ ( @$pArgs )
737
    {
738
        Message( "AR: unknown option $_ -- ignored\n" );
739
    }
740
 
741
#.. Target
742
#
743
    MakePrint( "#.. Library ($name)\n\n" );     # label
744
 
745
    MakeEntry( "\$(LIBDIR)/$name\$(GBE_TYPE).$::a:\t",
746
        "", "\\\n\t\t", ".$::o", @$pObjs );
747
 
748
#.. Build library rule (just append to standard rule)
749
#
750
    MakePrint( "\n\t\$(AR)\n\n" );
751
}
752
 
753
 
754
###############################################################################
755
#   ToolsetARMerge( $name, \@args, \@libs )
756
#       This subroutine takes the user options and builds the rules
757
#       required to build the library 'name' by merging the specified
758
#       libaries
759
#
760
#   Arguments:
761
#       --xxx                   No arguments currently defined
762
#
763
#   Output:
764
#       [ $(LIBDIR)/name$.${a}:   .... ]
765
#           ...
766
#
767
###############################################################################
768
 
769
sub ToolsetARMerge
770
{
771
    MakePrint( "\n\t\$(ARMERGE)\n\n" );
772
}
773
 
774
 
775
###############################################################################
289 dpurdie 776
#   ToolsetSHLD( $name, \@args, \@objs, \@libraries, $ver )
227 dpurdie 777
#       This subroutine takes the user options and builds the rules
339 dpurdie 778
#       required to link the Shared Library 'name'.
227 dpurdie 779
#
780
#   Arguments:
781
#   n/a
782
#
783
#   Output:
784
#       $(LIBDIR)/name:     $(LIBDIR)/shared
785
#           ln -s $shared $name
786
#
787
#       $(LIBDIR)/name.dep: $(GBE_OBJDIR)
788
#       $(LIBDIR)/name.dep: $(GBE_LIBDIR)
789
#       $(LIBDIR)/name.dep: $(GBE_PLATFORM).mk
790
#           $(SHLDDEPEND)
791
#
792
#       $(LIBDIR)/shared:   SHNAME=name
793
#       $(LIBDIR)/shared:   SHBASE=base
794
#       $(LIBDIR)/shared:   $(LIBDIR)/name.dep  \
795
#           $(OBJECTS)
796
#                           
797
#       ifneq "$(findstring $(IFLAG),23)" ""
798
#       -include            "$(LIBDIR)/name.dep"
799
#       endif
800
#
801
#       name_ld += ...
802
#           :
803
#
804
###############################################################################
805
 
806
sub ToolsetSHLD
807
{
289 dpurdie 808
    my( $name, $pArgs, $pObjs, $pLibs, $ver ) = @_;
6198 dpurdie 809
    my( $linkname, $soname, $shared, $dbgname, @preReqFiles, @scripts, $multi_scan );
4034 dpurdie 810
    my $sosuffix;
811
    my $noVersionedLib = $::ScmCompilerOpts{'NO_VERSIONED_DLLS'};
6198 dpurdie 812
    my $brokenLd = $::ScmCompilerOpts{'BROKEN_LDSCRIPTS'};
227 dpurdie 813
 
814
#.. Parse arguments
815
#
816
    foreach $_ ( @$pArgs )
817
    {
818
        if (/^--Def=(.*?)(\,(.*))?$/) {         # Library definition
819
            #
820
            #   Locate the Def file.
821
            #   If it is a generate file so it will be in the SRCS hash
822
            #   Otherwise the user will have to use Src to locate the file
823
            #
6198 dpurdie 824
            my $def = MakeSrcResolve($1);
825
 
826
            if ($brokenLd) {
827
                #   The linker cannot handle the linker script
828
                #   The work around is to split the script into two that it can handle
829
                #   Only works with a Linker Script with VERSION and EXTERN entries    
830
                my $index = scalar @ldFixups; 
831
                my %data;
832
                $data{src} = $def;
833
                $data{vs} = '$(OBJDIR)/linkscript_' . $index . '.def';
834
                $data{ls} = '$(OBJDIR)/linkscript_' . $index . '.scr';
835
                push @ldFixups, \%data;
836
 
837
                push @scripts, $data{ls};
838
                push @scripts, '--version-script=' . $data{vs};
839
 
840
                push @preReqFiles, $data{vs};
841
                push @preReqFiles, $data{ls};
842
 
843
            }  else {
844
                # Normal operation. Linker is not broken
845
                push @preReqFiles, $def;
846
                if ( $1 =~ m~\.def$~ ) {
847
                    $def = '--version-script=' .$def; # Old def file
848
                }
849
                push @scripts, $def;
227 dpurdie 850
            }
6198 dpurdie 851
 
227 dpurdie 852
        } elsif ( /^--MultiScan/i ) {
853
            $multi_scan = 1;
854
 
855
        } elsif ( /^--NoMultiScan/i ) {
856
            $multi_scan = 0;
857
 
339 dpurdie 858
        } elsif ( /^--SoNameSuffix=(.*)/i ) {
859
            $sosuffix = $1;
860
 
4034 dpurdie 861
        } elsif (/^--NoVersionDll/i) {
862
            $noVersionedLib = 1;
863
 
227 dpurdie 864
        } else {
865
            Message( "SHLD: unknown option $_ -- ignored\n" );
866
        }
867
    }
868
 
4034 dpurdie 869
    #
6459 dpurdie 870
    # Determine the 'soname' if none has been provided
4034 dpurdie 871
    #
872
    $sosuffix = '.' . $ver
873
        unless ( defined $sosuffix );
874
    $sosuffix = ''
875
        if ( $noVersionedLib );
876
 
339 dpurdie 877
#.. Various library names
227 dpurdie 878
#
339 dpurdie 879
    $linkname = "$name\$(GBE_TYPE).$::so";
4034 dpurdie 880
    $shared = $noVersionedLib ? $linkname : "$linkname.$ver";
339 dpurdie 881
    $soname = "$linkname$sosuffix";
4034 dpurdie 882
 
373 dpurdie 883
    my $shared_path = "\$(LIBDIR)/${shared}";
884
    my $dbg_path =  $shared_path . '.dbg';
227 dpurdie 885
 
886
#.. Cleanup rules
887
#
888
#   map     Map file
889
#   ln      Link from LIBDIR to BINDIR
890
#
261 dpurdie 891
    ToolsetGenerate( "\$(LIBDIR)/${name}.map" );
892
    ToolsetGenerate( "\$(LIBDIR)/${shared}" );
339 dpurdie 893
    ToolsetGenerate( "\$(BINDIR)/${soname}" );
373 dpurdie 894
    ToolsetGenerate( $dbg_path );
227 dpurdie 895
 
896
#.. Build rules
897
#
898
#   name        Base name
899
#   shared      Library name, includes GBE_TYPE specification
900
#
901
    my ($io) = ToolsetPrinter::New();
335 dpurdie 902
    my $dep = $io->SetShldTarget($shared);
227 dpurdie 903
 
904
    $io->Label( "Shared library", $name );
339 dpurdie 905
    PackageShlibAddFiles( $name, "\$(LIBDIR)/$shared" );
373 dpurdie 906
    PackageShlibAddFiles( $name, $dbg_path );
4034 dpurdie 907
 
227 dpurdie 908
    $io->Prt( "\$(LIBDIR)/${shared}:\tSHBASE=${name}\n" );
339 dpurdie 909
    $io->Prt( "\$(LIBDIR)/${shared}:\tSHNAME=${soname}\n" );
910
    $io->Prt( "\$(LIBDIR)/${shared}: \\\n\t\t${dep}" );
321 dpurdie 911
    $io->Entry( "", "", " \\\n\t\t", ".$::o", @$pObjs );
6198 dpurdie 912
    $io->Entry( "", "", " \\\n\t\t", "", @preReqFiles );
373 dpurdie 913
    $io->Prt( "\n\t\$(SHLD)" );
914
    $io->Prt( "\n\t\$(call LDSTRIP,$shared_path,$dbg_path)\n\n" );
321 dpurdie 915
 
339 dpurdie 916
#
917
#   Create soft links
918
#       'Real Name' to its 'Link Name'
919
#       'Real Name' to 'SoName' in the BINDIR (for testing I think)
920
#       'Real Name' to 'SoName' in the LIBDIR (if different)
921
#
4034 dpurdie 922
    if ( $shared ne $linkname)
923
    {
924
        $io->Label( "Shared library Symbolic Links", $name );
5882 dpurdie 925
        PackageShlibAddFiles( $name, "\$(LIBDIR)/$linkname", 'symlink=1' );
4034 dpurdie 926
        $io->Prt( "\$(LIBDIR)/$linkname:\t\\\n" .
927
                  "\t\t\$(GBE_BINDIR)\\\n" .
928
                  "\t\t\$(LIBDIR)/${shared}\n" .
5882 dpurdie 929
                  "\t\$(AA_PRE)(rm -f \$@; ln -s $shared \$@)\n\n" );
4034 dpurdie 930
    }
931
 
932
    $io->Label( "Shared library BINDIR Symbolic Links", $name );
5882 dpurdie 933
#    PackageShlibAddFiles( $name, "\$(BINDIR)/$soname", 'symlink=1' );
4034 dpurdie 934
    $io->Prt( "\$(BINDIR)/$soname:\t\\\n" .
339 dpurdie 935
              "\t\t\$(GBE_BINDIR)\\\n" .
936
              "\t\t\$(LIBDIR)/${shared}\n" .
4034 dpurdie 937
              "\t\$(AA_PRE)(rm -f \$@; ln -s ../\$(LIBDIR)/$shared \$@)\n\n" );
339 dpurdie 938
 
4034 dpurdie 939
    if ( $soname ne $shared )
339 dpurdie 940
    {
941
        $io->Label( "Shared library SoName Symbolic Links", $name );
5882 dpurdie 942
        PackageShlibAddFiles( $name, "\$(LIBDIR)/$soname", 'symlink=1' );
339 dpurdie 943
        $io->Prt( "\$(LIBDIR)/$soname:\t\\\n" .
944
                  "\t\t\$(GBE_LIBDIR)\\\n" .
945
                  "\t\t\$(LIBDIR)/${shared}\n" .
5882 dpurdie 946
                  "\t\$(AA_PRE)(rm -f \$@; ln -s $shared \$@)\n" );
339 dpurdie 947
    }
948
 
227 dpurdie 949
#.. Linker command file
950
#
951
#       Now the fun part... piecing together a variable $(name_shld)
952
#       which ends up in the command file.
953
#
339 dpurdie 954
    $io->Newline();
227 dpurdie 955
    $io->SetTag( "${name}_shld" );              # command tag
956
    $io->SetTerm( "\n" );
957
 
958
    $io->Label( "Linker commands", $name );     # label
959
 
960
                                                # object list
961
    $io->ObjList( $name, $pObjs, \&ToolsetObjRecipe );
962
 
963
    ToolsetLibStd( $pLibs );                    # push standard libraries
964
 
6198 dpurdie 965
    $io->Cmd( "-Wl," . join (',', @scripts) ) if (@scripts);
227 dpurdie 966
 
967
    $io->Cmd( "-Wl,--start-group" ) if ($multi_scan);
968
    $io->LibList( $name, $pLibs, \&ToolsetLibRecipe );
969
    $io->Cmd( "-Wl,--end-group" ) if ($multi_scan);
970
 
971
    $io->Newline();
972
 
335 dpurdie 973
    #.. Dependency link,
974
    #   Create a library dependency file
975
    #       Create command file to build applicaton dependency list
976
    #       from the list of dependent libraries
977
    #
978
    #       Create makefile directives to include the dependency
979
    #       list into the makefile.
980
    #
981
    $io->DepRules( $pLibs, \&ToolsetLibRecipe, "\$(LIBDIR)/${shared}" );
339 dpurdie 982
    $io->SHLDDEPEND($name, $soname);
227 dpurdie 983
}
984
 
985
 
986
###############################################################################
271 dpurdie 987
# Function        : ToolsetLD
227 dpurdie 988
#
271 dpurdie 989
# Description     : Takes the user options and builds the rules required to
990
#                   link the program 'name'.
227 dpurdie 991
#
271 dpurdie 992
# Inputs          : $name           - base name of the program
993
#                   $pArgs          - Ref to program arguments
994
#                   $pObjs          - Ref to program objects
995
#                   $pLibs          - Ref to program library list
227 dpurdie 996
#
271 dpurdie 997
# Returns         : Nothing
227 dpurdie 998
#
271 dpurdie 999
# Output:         : Rules and recipes to create a program
1000
#                       Create program rules and recipes
1001
#                       Create linker input script
1002
#                       Create library dependency list
1003
#                       Include library dependency information
227 dpurdie 1004
#
1005
sub ToolsetLD
1006
{
1007
    my( $name, $pArgs, $pObjs, $pLibs ) = @_;
1008
    my $static = $::ScmCompilerOpts{'STATIC_PROGS'};
1009
    my $multi_scan;
1010
 
1011
#.. Parse arguments
1012
#
1013
    foreach $_ ( @$pArgs )
1014
    {
1015
        if ( m/^--Static$/ ) {
1016
            $static = 1;
1017
 
1018
        } elsif ( m/^--Shared/ ) {
1019
            $static = 0;
1020
 
1021
        } elsif ( /^--MultiScan/i ) {
1022
            $multi_scan = 1;
1023
 
1024
        } elsif ( /^--NoMultiScan/i ) {
1025
            $multi_scan = 0;
1026
 
1027
        } else {
1028
            Message( "LD: unknown option $_ -- ignored\n" );
1029
        }
1030
    }
1031
 
271 dpurdie 1032
#.. Names of programs and components
1033
#
1034
    my $base = "\$(BINDIR)/${name}";
1035
    my $full = $base . $::exe;
1036
    my $map  = $base . '.map';
1037
    my $ld  =  $base . '.ld';
373 dpurdie 1038
    my $dbg =  $base . '.dbg';
271 dpurdie 1039
 
227 dpurdie 1040
#.. Cleanup rules
1041
#
271 dpurdie 1042
    ToolsetGenerate( $ld );
1043
    ToolsetGenerate( $map );
373 dpurdie 1044
    ToolsetGenerate( $dbg );
227 dpurdie 1045
 
1046
#.. Build rules
1047
#
1048
    my ($io) = ToolsetPrinter::New();
335 dpurdie 1049
    my $dep = $io->SetLdTarget( $name );
227 dpurdie 1050
 
271 dpurdie 1051
    $io->Prt( "$full : $dep " );
1052
    $io->Entry( "", "", "\\\n\t", ".$::o ", @$pObjs );
373 dpurdie 1053
    $io->Prt( "\n\t\$(LD)" );
1054
    $io->Prt( "\n\t\$(call LDSTRIP,$full,$dbg)\n\n" );
227 dpurdie 1055
 
271 dpurdie 1056
 
227 dpurdie 1057
#.. Linker command file
1058
#
1059
#       Now the fun part... piecing together a variable $(name_ld)
1060
#       which ends up in the command file.
1061
#
1062
    $io->SetTag( "${name}_ld" );                # macro tag
1063
    $io->SetTerm( "\n" );
1064
 
1065
    $io->Label( "Linker commands", $name );     # label
1066
 
1067
    $io->Cmd( "-static" ) if ($static);         # Link as a static program
1068
 
1069
                                                # object list
1070
    $io->ObjList( $name, $pObjs, \&ToolsetObjRecipe );
1071
 
1072
    ToolsetLibStd( $pLibs );                    # push standard libraries
1073
 
1074
                                                # library list
1075
    $io->Cmd( "-Wl,--start-group" ) if ($multi_scan);
1076
    $io->LibList( $name, $pLibs, \&ToolsetLibRecipe );
1077
    $io->Cmd( "-Wl,--end-group" ) if ($multi_scan);
1078
 
5744 dpurdie 1079
    #   Add Compilers sysroot library path
1080
    #   Only required for a 'native' compiler that is not fully installed on the host
1081
    #   ie: The run-time can't locate the required glic components
5796 dpurdie 1082
    if ($GCCRPath)
1083
    {
1084
        $io->Cmd( "-Wl,-rpath=$GCCRPath" );
1085
        $io->Cmd( "-Wl,--dynamic-linker=$GCCRPath/ld-linux.so.2" ) if ($GCCRPath);
1086
    }
5744 dpurdie 1087
 
227 dpurdie 1088
    $io->Newline();
1089
 
335 dpurdie 1090
    #.. Dependency link,
1091
    #   Create a library dependency file
1092
    #       Create command file to build applicaton dependency list
1093
    #       from the list of dependent libraries
1094
    #
1095
    #       Create makefile directives to include the dependency
1096
    #       list into the makefile.
1097
    #
1098
    $io->DepRules( $pLibs, \&ToolsetLibRecipe, $base );
1099
    $io->LDDEPEND();
271 dpurdie 1100
 
1101
#.. Package up the program and other artifacts
1102
#
1103
    PackageProgAddFiles ( $name, $full );
6294 dpurdie 1104
    PackageProgAddFiles ( $name, $dbg, "Class=debug" );
271 dpurdie 1105
 
227 dpurdie 1106
}
1107
 
4778 dpurdie 1108
  #-------------------------------------------------------------------------------
1109
# Function        : ToolsetPostprocess 
1110
#
1111
# Description     : Last chance by the toolset to perform processing
1112
#                   All Directives have been processed
1113
#
1114
#                   If automated unit test are being used,
1115
#                   then we need to post process the results
1116
#
1117
# Inputs          : None
1118
#
1119
# Returns         : 
1120
#
1121
sub ToolsetPostprocess
1122
{
1123
    ToolsetPreprocessTests();
1124
    ToolsetPostprocessTests();
1125
    ToolsetCollateTestResults();
6198 dpurdie 1126
    ToolsetGenLdScripts();
4778 dpurdie 1127
}
227 dpurdie 1128
 
4728 dpurdie 1129
###############################################################################
1130
# Function        : ToolsetPreprocessTests
1131
#
5884 dpurdie 1132
# Description     : Generate $(OBJDIR)/lcov-baseline.info 
1133
#                   Generate full coverage info
4728 dpurdie 1134
#
1135
# Inputs          : None
1136
#
1137
# Returns         : Nothing
1138
#
1139
# Output:         : Rules and recipes to run before unit tests
1140
#
1141
sub ToolsetPreprocessTests
1142
{
1143
    my ($io) = ToolsetPrinter::New();
1144
    if ( $UseGcov && scalar(keys %::OBJSOURCE) > 0 )
1145
    {
5884 dpurdie 1146
        #
1147
        #   Setup Env so that the files created by GCOV are within the package
1148
        #   being created. Elsewise they will be created all over the file 
1149
        #   system in the original location where the external objects were created.
1150
        #
1151
        $io->PrtLn('GCOV_PREFIX := $(abspath $(INTERFACEDIR)/gcov)' );
1152
        $io->PrtLn('GCOV_PREFIX_STRIP := 0' );
1153
        $io->PrtLn('export GCOV_PREFIX GCOV_PREFIX_STRIP' );
1154
        $io->Newline();
1155
 
1156
        #
1157
        #   GCOV_PKGBASE - used to 'extract' coverage artifacts
1158
        #   Used to limit the coverage report to files that are within this package
1159
        #   Ideally it should be the root of the package, but this is not always known
1160
        #   Use the first two path elements of the current package
1161
        #       Really just want to filter out compiler bits
1162
        #     
1163
 
1164
        $io->PrtLn('GCOV_PKGBASE :=  $(subst $(space),/,$(space)$(wordlist 1,2,$(subst /,$(space),$(CURDIR))))' );
1165
        $io->PrtLn('GCOV_VERBOSE :=  $(if $(VERBOSE_OPT),,--quiet)' );
1166
        $io->Newline();
1167
 
4778 dpurdie 1168
        my $ruleName = 'preprocess_gcov_data';
4728 dpurdie 1169
        my $finaldir='$(LOCALDIR)/lcov/$(GBE_PLATFORM)$(GBE_TYPE)';
1170
        my $final=$finaldir . '/lcov-final.info';
1171
 
4778 dpurdie 1172
        ToolsetAddUnitTestPreProcess($ruleName);
1173
        $io->PrtLn('.PHONY: ' . $ruleName );
6798 dpurdie 1174
        $io->PrtLn($ruleName . ': $(OBJDIR)' );
5884 dpurdie 1175
        $io->PrtLn("\t" . '${XX_PRE}$(rm) -f ${GCOV_PREFIX}/$(CURDIR)/$(OBJDIR)/*.gcda' );
1176
        $io->PrtLn("\t" . '${XX_PRE}$(rm) -f $(OBJDIR)/*.gcda' );
4728 dpurdie 1177
        $io->PrtLn("\t" . '${XX_PRE}$(rm) -f ' . $final);
1178
        $io->PrtLn("\t" . '${XX_PRE}lcov'
5884 dpurdie 1179
                        . ' $(GCOV_VERBOSE)'
4835 dpurdie 1180
                        . ' --capture'
1181
                        . ' --initial'
5884 dpurdie 1182
                        . ' --base-directory $(CURDIR)'
4835 dpurdie 1183
                        . ' --directory $(OBJDIR)'
5731 dpurdie 1184
                        . ' --gcov-tool $(GCC_GCOVTOOL)' 
5884 dpurdie 1185
                       . ' --output-file $(OBJDIR)/lcov-baseline.info' );
4778 dpurdie 1186
        $io->Newline();
5884 dpurdie 1187
        ToolsetGenerate( '$(OBJDIR)/lcov-baseline.info' );
4728 dpurdie 1188
    }
1189
}
1190
 
1191
 
1192
###############################################################################
1193
# Function        : ToolsetPostprocessTests
1194
#
5884 dpurdie 1195
# Description     : Merge this sub-components bits into the the final coverage
1196
#                   file in lcov-baseline.info
1197
#                   
1198
#                   Need to locate the .gcda files and place them in the same directory
1199
#                   as the .gcno files that were created during preprocssing
1200
#                   
1201
#                   Then we can add our trace bits into the file coverage file
4728 dpurdie 1202
#
1203
# Inputs          : None
1204
#
1205
# Returns         : Nothing
1206
#
1207
# Output:         : Rules and recipes to run after the unit tests
1208
#
1209
sub ToolsetPostprocessTests
1210
{
1211
    my ($io) = ToolsetPrinter::New();
1212
    if ( $UseGcov && scalar(keys %::OBJSOURCE) > 0 )
1213
    {
4778 dpurdie 1214
        my $ruleName = 'postprocess_gcov_data';
4728 dpurdie 1215
        my $finaldir='$(LOCALDIR)/lcov/$(GBE_PLATFORM)$(GBE_TYPE)';
1216
        my $final=$finaldir . '/lcov-final.info';
1217
 
4778 dpurdie 1218
        ToolsetAddUnitTestPostProcess($ruleName);
1219
 
1220
        $io->PrtLn('.PHONY: ' . $ruleName );
1221
        $io->PrtLn($ruleName . ':' );
5884 dpurdie 1222
        $io->PrtPart("\t" . '$(XX_PRE)if [ -d "${GCOV_PREFIX}/$(CURDIR)/$(OBJDIR)" ]; then' ); 
1223
        $io->PrtPart("\t\t" . 'cd ${GCOV_PREFIX}/$(CURDIR);');
1224
        $io->PrtPart("\t\t" . 'find $(OBJDIR) -name \'*.gcda\' -exec cp --parent {} $(CURDIR) \\; ;');
1225
#        $io->PrtPart("\t" . 'else');
1226
#        $io->PrtPart("\t\t" . 'echo NO .gcda DATA for $(CURDIR);');
1227
        $io->PrtLn  ("\t" . 'fi' );
4728 dpurdie 1228
        $io->PrtLn  ("\t" . '$(XX_PRE)$(mkdir) -p ' . $finaldir);
5884 dpurdie 1229
        $io->PrtPart("\t" . '$(XX_PRE)GCDA_COUNT=$$(find $(OBJDIR) -name "*.gcda" | wc -l);' ); 
1230
        $io->PrtPart("\t" . 'if [ "$${GCDA_COUNT}" -eq "0" ]; then ');
4728 dpurdie 1231
        $io->PrtPart("\t\t" . 'if [ ! -e ' . $final . " ]; then");
1232
        $io->PrtPart("\t\t\t" . '$(cp) $(OBJDIR)/lcov-baseline.info ' . $final . ';');
1233
        $io->PrtPart("\t\t" . 'else');
1234
        $io->PrtPart("\t\t\t" . 'lcov'
5884 dpurdie 1235
                          . ' $(GCOV_VERBOSE)'
4835 dpurdie 1236
                          . $LcovExplicitBranch
4728 dpurdie 1237
                          . ' --add-tracefile $(OBJDIR)/lcov-baseline.info'
1238
                          . ' --add-tracefile ' . $final
5731 dpurdie 1239
                          . ' --gcov-tool $(GCC_GCOVTOOL)' 
4728 dpurdie 1240
                          . ' --output-file $(OBJDIR)/lcov-merge.info'
1241
                          . ';'); 
1242
        $io->PrtPart("\t\t\t" . '$(rm) -f ' . $final . ';');
1243
        $io->PrtPart("\t\t\t" . '$(mv) $(OBJDIR)/lcov-merge.info ' . $final . ';');
1244
        $io->PrtPart("\t\t" . 'fi' . ';');
1245
        $io->PrtPart("\t" . 'else');
1246
        $io->PrtPart("\t\t" . 'lcov'
5884 dpurdie 1247
                        . ' $(GCOV_VERBOSE)'
1248
                        . $LcovExplicitBranch
4728 dpurdie 1249
                        . ' --capture'
5884 dpurdie 1250
                        . ' --base-directory $(CURDIR)'
4728 dpurdie 1251
                        . ' --directory $(OBJDIR)'
5731 dpurdie 1252
                        . ' --gcov-tool $(GCC_GCOVTOOL)' 
4728 dpurdie 1253
                        . ' --output-file $(OBJDIR)/lcov-capture.info' 
1254
                        . ';'); 
1255
        $io->PrtPart("\t\t" . 'if [ ! -e ' . $final . " ]; then");
1256
        $io->PrtPart("\t\t\t" . 'lcov'
5884 dpurdie 1257
                          . ' $(GCOV_VERBOSE)'
4835 dpurdie 1258
                          . $LcovExplicitBranch
4728 dpurdie 1259
                          . ' --add-tracefile $(OBJDIR)/lcov-baseline.info'
5884 dpurdie 1260
                          . ' --add-tracefile $(OBJDIR)/lcov-capture.info'
5731 dpurdie 1261
                          . ' --gcov-tool $(GCC_GCOVTOOL)' 
4728 dpurdie 1262
                          . ' --output-file ' .  $final
1263
                          . ';'); 
1264
        $io->PrtPart("\t\t" . 'else');
1265
        $io->PrtPart("\t\t\t" . 'lcov'
5884 dpurdie 1266
                          . ' $(GCOV_VERBOSE)'
4835 dpurdie 1267
                          . $LcovExplicitBranch
4728 dpurdie 1268
                          . ' --add-tracefile $(OBJDIR)/lcov-baseline.info'
5884 dpurdie 1269
                          . ' --add-tracefile $(OBJDIR)/lcov-capture.info'
4728 dpurdie 1270
                          . ' --add-tracefile ' . $final
5731 dpurdie 1271
                          . ' --gcov-tool $(GCC_GCOVTOOL)' 
4728 dpurdie 1272
                          . ' --output-file $(OBJDIR)/lcov-merge.info'
1273
                          . ';'); 
1274
        $io->PrtPart("\t\t\t" . '$(rm) -f ' . $final . ';');
1275
        $io->PrtPart("\t\t\t" . '$(mv) $(OBJDIR)/lcov-merge.info ' . $final . ';');
1276
        $io->PrtPart("\t\t" . 'fi' . ';');
1277
        $io->PrtLn  ("\t" . 'fi');
4778 dpurdie 1278
        $io->Newline();
5817 dpurdie 1279
 
1280
        ToolsetGenerate ('$(OBJDIR)/lcov-capture.info' );
1281
        ToolsetGenerate ($final);
1282
 
4728 dpurdie 1283
    }
1284
}
1285
 
1286
 
1287
###############################################################################
1288
# Function        : ToolsetCollateTestResults
1289
#
5884 dpurdie 1290
# Description     : Process the lcov-final.info by
1291
#                       Extract parts generated by files in this package
1292
#                       Remove parts generated by files in the interface directory
1293
#                           They are the results of a 'BuildPkgArchive'
4728 dpurdie 1294
#
1295
# Inputs          : None
1296
#
1297
# Returns         : Nothing
1298
#
1299
# Output:         : Rules and recipes to run after unit test result 
1300
#                   postprocessing.
1301
#
1302
sub ToolsetCollateTestResults
1303
{
1304
    my ($io) = ToolsetPrinter::New();
1305
    if ( $UseGcov && scalar(keys %::OBJSOURCE) > 0 )
1306
    {
4778 dpurdie 1307
        my $ruleName = 'collate_gcov_results';
5884 dpurdie 1308
        my $finaldir = '$(LOCALDIR)/lcov/$(GBE_PLATFORM)$(GBE_TYPE)';
1309
        my $final     = $finaldir . '/lcov-final.info';
5885 dpurdie 1310
        my $finalTmp  = $finaldir . '/lcov-extracted.info';
1311
        my $finalTmp1 = $finaldir . '/lcov-filtered.info';
4778 dpurdie 1312
 
5884 dpurdie 1313
        ToolsetGenerate ( $final );
1314
        ToolsetGenerate ( $finalTmp );
1315
        ToolsetGenerate ( $finalTmp1 );
1316
 
4778 dpurdie 1317
        ToolsetAddUnitTestCollateProcess($ruleName);
4728 dpurdie 1318
 
1319
        my $reportdir='$(PKGDIR)/lcov/$(GBE_PLATFORM)$(GBE_TYPE)';
1320
        my $reportindex=$reportdir . '/index.html';
4778 dpurdie 1321
        $io->PrtLn('.PHONY: ' . $ruleName );
1322
        $io->PrtLn($ruleName . ': ' . $reportindex);
5884 dpurdie 1323
 
4728 dpurdie 1324
        $io->Newline();
1325
        $io->PrtLn($reportindex . ': ' . $final);
5884 dpurdie 1326
        $io->PrtPart("\t" . 'lcov'
1327
                        . ' $(GCOV_VERBOSE)'
1328
                        . $LcovExplicitBranch
1329
                        . ' --extract '. $final .' "$(GCOV_PKGBASE)/*"'
1330
                        . ' --gcov-tool $(GCC_GCOVTOOL)' 
1331
                        . ' --output-file ' . $finalTmp
1332
                        . ';'); 
1333
        $io->PrtPart("\t" . 'lcov'
1334
                        . ' $(GCOV_VERBOSE)'
1335
                        . $LcovExplicitBranch
1336
                        . ' --remove '. $finalTmp .' "$(abspath $(INTERFACEDIR))/*"'
1337
                        . ' --gcov-tool $(GCC_GCOVTOOL)' 
1338
                        . ' --output-file ' .$finalTmp1
1339
                        . ';'); 
4728 dpurdie 1340
        $io->PrtLn("\t" . 'genhtml'
5884 dpurdie 1341
                      . ' $(GCOV_VERBOSE)'
4728 dpurdie 1342
                      . ' --frames'
1343
                      . ' --show-details'
1344
                      . ' --function-coverage'
1345
                      . ' --branch-coverage'
1346
                      . ' --output-directory ' . $reportdir
1347
                      . ' --legend'
5885 dpurdie 1348
                      . ' --demangle-cpp' 
1349
                      . ' --title "$(GBE_PBASE) $(BUILDVER)"'
5884 dpurdie 1350
                      . ' ' . $finalTmp1);
4778 dpurdie 1351
        $io->Newline();
4728 dpurdie 1352
    }
1353
}
1354
 
6198 dpurdie 1355
#-------------------------------------------------------------------------------
1356
# Function        : ToolsetGenLdScripts 
1357
#
1358
# Description     : Generate Linker (ld) scripts to to support the Broken Linker
1359
#                   Enabled via BROKEN_LDSCRIPTS
1360
#                   The linker cannot handle a linkerscript with a 'VERSION" section
1361
#                   The linker can handle a linker script with an EXTERN section
1362
#                   and a --version-script
1363
#                   
1364
#                   This workaround will take the linker script and break it into two
1365
#                   parts. This must be done at make-time in case the linker script is
1366
#                   generated.
1367
#                   
1368
#                   Use a feature of Pattern Rules. Handling of multiple targets
1369
#                   The pattern (%) is a '.'. 
1370
#                   It may be substituted as $* in the output.
1371
#                   
1372
#                   file1%out file2%out : infile
1373
#                       SomeProg file1$*out file2$*out      - Using pattern substitution
1374
#                       SomeProg file1.out file2.out        - Alternate command
1375
#                   
1376
# Inputs          : None 
1377
#
1378
# Returns         : Nothing
1379
#
1380
sub ToolsetGenLdScripts
1381
{
1382
    return unless @ldFixups;
1383
    Verbose('ToolsetGenLdScripts');
4728 dpurdie 1384
 
6198 dpurdie 1385
    my ($io) = ToolsetPrinter::New();
1386
    $io->PrtLn('# Broken Linker Support');
1387
    foreach my $entry (@ldFixups)
1388
    {
1389
        (my $ls = $entry->{ls}) =~ s~\.~%~;
1390
        (my $vs = $entry->{vs}) =~ s~\.~%~;
1391
 
1392
        $io->Newline();
1393
        $io->PrtLn("$vs $ls:  $entry->{src} \$(SCM_MAKEFILE)" );
1394
 
1395
        $io->PrtLn("\t\$(GBE_PERL) -Mjats_runtime_gcc -e splitscript -- --src=$entry->{src} --vs=$entry->{vs} --ls=$entry->{ls}" );
1396
        ToolsetGenerate ($entry->{vs} );
1397
        ToolsetGenerate ($entry->{ls} );
1398
    }
1399
}
1400
 
4728 dpurdie 1401
###############################################################################
1402
#   ToolsetARLINT( $name, \@args, \@objs )
1403
#       This subroutine takes the user options and builds the rules
1404
#       required to lint the static library 'name'.
1405
#
1406
#   Arguments:
1407
#       --xxx                   No arguments currently defined
1408
#
1409
#   Output:
1410
#       [ $(LIBDIR)/name$_lint:   .... ]
1411
#           $(ARLINT)
1412
#
1413
###############################################################################
1414
 
1415
sub ToolsetARLINT
1416
{
1417
    if ( $UseCppcheck )
1418
    {
1419
        CppcheckAR( @_ );
1420
    }
1421
}
1422
 
1423
 
1424
###############################################################################
1425
#   ToolsetSHLDLINT $name, \@args, \@objs, \@libraries )
1426
#       This subroutine takes the user options and builds the rules
1427
#       required to lint the shared library 'name'.
1428
#
1429
#   Arguments:
1430
#       (none)
1431
#
1432
#   Output:
1433
#       [ $(LIBDIR)/$name_lint:   .... ]
1434
#           $(SHLIBLINT)
1435
#
1436
###############################################################################
1437
 
1438
sub ToolsetSHLDLINT
1439
{
1440
    if ( $UseCppcheck )
1441
    {
1442
        CppcheckSHLD( @_ );
1443
    }
1444
}
1445
 
1446
 
1447
###############################################################################
1448
#   ToolsetLD( $name, \@args, \@objs, \@libraries, \@csrc, \@cxxsrc )
1449
#       This subroutine takes the user options and builds the rules
1450
#       required to lint the program 'name'.
1451
#
1452
#   Arguments:
1453
#       (none)
1454
#
1455
#   Output:
1456
#       [ $(BINDIR)/$name_lint:   .... ]
1457
#           $(LDLINT)
1458
#
1459
###############################################################################
1460
 
1461
sub ToolsetLDLINT
1462
{
1463
    if ( $UseCppcheck )
1464
    {
1465
        CppcheckLD( @_ );
1466
    }
1467
}
1468
 
227 dpurdie 1469
########################################################################
1470
#
1471
#   Push standard "system" libraries. This is a helper function
1472
#   used within this toolset.
1473
#
1474
#   Arguments:
1475
#       $plib       Reference to library array.
1476
#
1477
########################################################################
1478
 
1479
sub ToolsetLibStd
1480
{
1481
}
1482
 
1483
 
1484
########################################################################
1485
#
1486
#   Generate a linker object recipe.  This is a helper function used 
1487
#   within this toolset.
1488
#
1489
#   Arguments:
1490
#       $io         I/O stream
1491
#
1492
#       $target     Name of the target
1493
#
1494
#       $obj        Library specification
1495
#
1496
########################################################################
1497
 
1498
sub ToolsetObjRecipe
1499
{
1500
    my ($io, $target, $obj) = @_;
1501
 
1502
    $io->Cmd( "\$(strip $obj).$::o" );
1503
}
1504
 
1505
 
1506
###############################################################################
1507
#
1508
#   Parse a linker lib list
1509
#   This is a helper function used within this toolset
1510
#
1511
#   Arguments:
1512
#       $target     Name of the target
1513
#
1514
#       $lib        Library specification
1515
#
1516
#       $tag        Tag (user specified)
1517
#
1518
#       $dp         If building a depend list, the full target name.
1519
#
1520
###############################################################################
1521
 
1522
sub ToolsetLibRecipe
1523
{
1524
    my ($io, $target, $lib, $dp) = @_;
1525
 
1526
    if ( ! defined($dp) ) {                     # linker
1527
        $lib =~ s/^lib//;                       # .. remove leading 'lib'
1528
        $io->Cmd( "-l$lib" );
1529
 
1530
    } else {                                    # depend
1531
        $io->Cmd( "$dp:\t@(vlib2,$lib,GCC_LIB)" );
1532
 
1533
    }
1534
}
1535
 
1536
#.. Successful termination
1537
1;
1538