Subversion Repositories DevTools

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

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