Subversion Repositories DevTools

Rev

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

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