Subversion Repositories DevTools

Rev

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