Subversion Repositories DevTools

Rev

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

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