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
 
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/',
148
        PACKAGE_ARCH => 'el7.x86_64',
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};
227 dpurdie 416
    }
417
    else
418
    {
373 dpurdie 419
        $GCCRoot = '/usr';
420
        $GCCBin = 'gcc';
421
        $GCCAr = 'ar';
422
        $GCCObjCopy =  'objcopy';
227 dpurdie 423
    }
4728 dpurdie 424
 
425
    #
426
    #   When running under gcov we need to instruct GCC to perform code coverage
427
    #   generation in both C flags and LD flags
428
    #
429
    if ( $UseGcov )
430
    {
431
        $GCCFlags .= ' -coverage';
432
        $LDFlags  .= ' -coverage';
433
    }
434
 
435
    #
436
    #   When running with cppcheck we need to include it in our environment
437
    #
438
    if ( $UseCppcheck )
439
    {
440
        ToolsetRequire( "cppcheck" );
441
        PlatformDefine( "CPPCHECK_PLATFORM := unix32" );
442
    }
443
 
227 dpurdie 444
 
445
#.. Define GCC environment
446
#
447
    PlatformDefine( "
448
#################################################
449
# GCC toolchain definitions 
450
#
451
#..");
369 dpurdie 452
    PlatformDefine( "GCC_TARGET         := $GCCTarget" );
453
    PlatformDefine( "GCC_ROOT           := $GCCRoot" );
454
    PlatformDefine( "GCC_CC             := $GCCBin" );
455
    PlatformDefine( "GCC_AR             := $GCCAr" );
373 dpurdie 456
    PlatformDefine( "GCC_OBJCOPY        := $GCCObjCopy" );
5731 dpurdie 457
    PlatformDefine( "GCC_GCOVTOOL       := $GCCGcovTool" );
369 dpurdie 458
    PlatformDefine( "GCC_CFLAGS         := $GCCFlags" ) if defined $GCCFlags;
4034 dpurdie 459
    PlatformDefine( "GCC_CFLAGSP        := $GCCFlagsP" ) if defined $GCCFlagsP;
460
    PlatformDefine( "GCC_CFLAGSD        := $GCCFlagsD" ) if defined $GCCFlagsD;
4728 dpurdie 461
    PlatformDefine( "GCC_LDFLAGS        := $LDFlags" ) if defined $LDFlags;
5726 dpurdie 462
    PlatformDefine( "GCC_CXXFLAGS       := $GCCXXFlags" ) if defined $GCCXXFlags;
369 dpurdie 463
 
5726 dpurdie 464
 
227 dpurdie 465
    #
466
    #   Required since this toolset advertises: ScmToolsetCompilerPath
467
    #
369 dpurdie 468
    PlatformDefine( "SCM_COMPILERPATH   := \$\{GCC_CC\}" );
3967 dpurdie 469
 
470
    #
471
    #   Sanity checking
472
    #
473
    PlatformDefine( "GCC_EVERSION       := " . $GCCToolchain->{VERSION} ) if defined $GCCToolchain->{VERSION};
474
    PlatformDefine( "GCC_EMACHINE       := " . $GCCToolchain->{MACHINE} ) if defined $GCCToolchain->{MACHINE};
475
 
476
    #
477
    #   Option indication of packaging architecture
478
    #   Used by non-embedded systems for packaging. See debian_packager
479
    #
480
    PlatformDefine( "PACKAGE_ARCH       := $PkgArch" ) if (defined $PkgArch);
369 dpurdie 481
    PlatformDefine( "" );
227 dpurdie 482
 
483
#.. Piece the world together
484
#
3967 dpurdie 485
    Init( 'gcc' );
227 dpurdie 486
    ToolsetDefines( "gcc.def" );
487
    ToolsetRules( "gcc.rul" );
488
    ToolsetRules( "standard.rul" );
489
 
4094 dpurdie 490
 
491
    PlatformDefine( "CTAGS_EXE:= ctags" );
492
    ToolsetRequire( "exctags" );                # and Exuberant Ctags
493
 
227 dpurdie 494
#   Create a standard data structure
495
#   This is a hash of hashes
496
#       The first hash is keyed by CompileOption keyword
497
#       The second hash contains pairs of values to set or remove
498
#
499
    %::ScmToolsetCompilerOptions =
500
    (
501
        #
502
        #   Control the thread model to use
503
        #   This will affect the compiler options and the linker options
504
        #
505
        'staticprogs'        => { 'STATIC_PROGS' , '1' },      # Progams link staticlly
506
        'no_staticprogs'     => { 'STATIC_PROGS' , undef },    # Default
4034 dpurdie 507
        'noversiondll'       => { 'NO_VERSIONED_DLLS', 1 },    # Matches usage elsewhere
5115 dpurdie 508
        'pic'                => { 'GEN_PIC' , '1' },           # Force PIC for static libs
509
        'nopic'              => { 'GEN_PIC' , undef },         # No Pic on Static libs
227 dpurdie 510
    );
511
 
512
    #
513
    #   Set default options
514
    #
515
    $::ScmCompilerOpts{'STATIC_PROGS'} = undef;
4034 dpurdie 516
    $::ScmCompilerOpts{'NO_VERSIONED_DLLS'} = undef;
517
 
518
    #
519
    #   Process toolset-specfic compiler options
520
    #
521
    if ( exists $GCCToolchain->{COMPILER_OPTIONS} )
522
    {
523
        CompileOptions('*', split(',',$GCCToolchain->{COMPILER_OPTIONS}) );
524
    }
227 dpurdie 525
}
526
 
4094 dpurdie 527
###############################################################################
528
#   ToolsetCTAGS()
529
#       This subroutine takes the user options and builds the rules
530
#       required to build the CTAGS database.
531
#
532
#   Arguments:
533
#       --xxx                   No arguments currently defined
534
#
535
#   Output:
536
#       [ctags:]
537
#           $(EXCTAGS)
538
#
539
###############################################################################
227 dpurdie 540
 
4094 dpurdie 541
sub ToolsetCTAGS
542
{
543
    EXCTAGS( @_ );
544
}
545
 
546
 
227 dpurdie 547
###############################################################################
548
#   ToolsetCC( $source, $obj, \@args )
549
#       This subroutine takes the user options and builds the rule(s)
550
#       required to compile the source file 'source' to 'obj'
551
#
552
###############################################################################
553
 
554
sub ToolsetCC
555
{
556
    my( $source, $obj, $pArgs ) = @_;
557
    my( $cflags, $file ) = "";
558
 
559
    foreach $_ ( @$pArgs ) {
560
        if (/--Shared$/) {                      # Building a 'shared' object
561
            $cflags  = "$cflags \$(SHCFLAGS)";
562
        } else {
563
            Message( "CC: unknown option $_ -- ignored\n" );
564
        }
565
    }
566
 
567
    MakePrint( "\n\t\$(CC)\n" );
568
    if ( $cflags )
569
    {                                           # object specific CFLAGS
570
        MakePadded( 4, "\$(OBJDIR)/$obj.$::o:" );
571
        MakePrint( "\tCFLAGS +=$cflags\n" );
572
    }
573
 
574
    $file = StripExt( $obj );                   # Metric working file
575
    ToolsetGenerate( "\$(OBJDIR)/$file.met" );
4728 dpurdie 576
 
577
    if ( $UseGcov )
578
    {
579
        ToolsetGenerate( '$(OBJDIR)/' . $file . '.gcno' );
580
        ToolsetGenerate( '$(OBJDIR)/' . $file . '.gcda' );
581
    }
227 dpurdie 582
}
583
 
584
 
585
###############################################################################
586
#   ToolsetCCDepend( $depend, \@sources )
587
#       This subroutine takes the user options and builds the
588
#       rule(s) required to build the dependencies for the source
589
#       files 'sources' to 'depend'.
590
#
591
###############################################################################
592
 
593
sub ToolsetCCDepend
594
{
595
    MakePrint( "\t\$(CCDEPEND)\n" );
596
}
597
 
598
 
599
###############################################################################
600
#   ToolsetCXX( $source, $obj, \@args )
601
#       This subroutine takes the user options and builds the rule(s)
602
#       required to compile the source file 'source' to 'obj'
603
#
604
###############################################################################
605
 
606
sub ToolsetCXX
607
{
608
    my( $source, $obj, $pArgs ) = @_;
609
    my( $cflags, $file ) = "";
610
 
611
    foreach $_ ( @$pArgs ) {
612
        if (/--Shared$/) {                      # Building a 'shared' object
613
            $cflags  = "$cflags \$(SHCXXFLAGS)";
614
        } else {
615
            Message( "CXX: unknown option $_ -- ignored\n" );
616
        }
617
    }
618
 
619
    MakePrint( "\n\t\$(CXX)\n" );
620
    if ( $cflags )
621
    {                                           # object specific CFLAGS
622
        MakePadded( 4, "\$(OBJDIR)/$obj.$::o:" );
623
        MakePrint( "\tCXXFLAGS +=$cflags\n" );
624
    }
625
 
626
    $file = StripExt( $obj );                   # Metric working file
627
    ToolsetGenerate( "\$(OBJDIR)/$file.met" );
4728 dpurdie 628
 
629
    if ( $UseGcov )
630
    {
631
        ToolsetGenerate( '$(OBJDIR)/' . $file . '.gcno' );
632
        ToolsetGenerate( '$(OBJDIR)/' . $file . '.gcda' );
633
    }
227 dpurdie 634
}
635
 
636
 
637
###############################################################################
638
#   ToolsetCXXDepend( $depend, \@sources )
639
#       This subroutine takes the user options and builds the
640
#       rule(s) required to build the dependencies for the source
641
#       files 'sources' to 'depend'.
642
#
643
###############################################################################
644
 
645
sub ToolsetCXXDepend
646
{
287 dpurdie 647
    ToolsetCCDepend();
227 dpurdie 648
}
649
 
650
 
651
###############################################################################
652
#   ToolsetAS( $source, $obj, \@args )
653
#       This subroutine takes the user options and builds the rule(s)
654
#       required to compile the source file 'source' to 'obj'
655
#
656
###############################################################################
657
 
658
sub ToolsetAS
659
{
660
    MakePrint( "\n\t\$(AS)\n" );
661
}
662
 
663
sub ToolsetASDepend
664
{
665
}
666
 
667
 
668
###############################################################################
669
#   ToolsetAR( $name, \@args, \@objs )
670
#       This subroutine takes the user options and builds the rules
671
#       required to build the library 'name'.
672
#
673
#   Arguments:
674
#       n/a
675
#
676
#   Output:
677
#       $(BINDIR)/name$.${a}:   .... ]
678
#           $(AR)
679
#
680
#       name_ld += ...  Linker command file
681
#           :
682
#
683
#       name_dp += ...  Dependency list
684
#           :
685
#
686
###############################################################################
687
 
688
sub ToolsetAR
689
{
690
    my( $name, $pArgs, $pObjs ) = @_;
691
 
692
#.. Parse arguments
693
#
694
    foreach $_ ( @$pArgs )
695
    {
696
        Message( "AR: unknown option $_ -- ignored\n" );
697
    }
698
 
699
#.. Target
700
#
701
    MakePrint( "#.. Library ($name)\n\n" );     # label
702
 
703
    MakeEntry( "\$(LIBDIR)/$name\$(GBE_TYPE).$::a:\t",
704
        "", "\\\n\t\t", ".$::o", @$pObjs );
705
 
706
#.. Build library rule (just append to standard rule)
707
#
708
    MakePrint( "\n\t\$(AR)\n\n" );
709
}
710
 
711
 
712
###############################################################################
713
#   ToolsetARMerge( $name, \@args, \@libs )
714
#       This subroutine takes the user options and builds the rules
715
#       required to build the library 'name' by merging the specified
716
#       libaries
717
#
718
#   Arguments:
719
#       --xxx                   No arguments currently defined
720
#
721
#   Output:
722
#       [ $(LIBDIR)/name$.${a}:   .... ]
723
#           ...
724
#
725
###############################################################################
726
 
727
sub ToolsetARMerge
728
{
729
    MakePrint( "\n\t\$(ARMERGE)\n\n" );
730
}
731
 
732
 
733
###############################################################################
289 dpurdie 734
#   ToolsetSHLD( $name, \@args, \@objs, \@libraries, $ver )
227 dpurdie 735
#       This subroutine takes the user options and builds the rules
339 dpurdie 736
#       required to link the Shared Library 'name'.
227 dpurdie 737
#
738
#   Arguments:
739
#   n/a
740
#
741
#   Output:
742
#       $(LIBDIR)/name:     $(LIBDIR)/shared
743
#           ln -s $shared $name
744
#
745
#       $(LIBDIR)/name.dep: $(GBE_OBJDIR)
746
#       $(LIBDIR)/name.dep: $(GBE_LIBDIR)
747
#       $(LIBDIR)/name.dep: $(GBE_PLATFORM).mk
748
#           $(SHLDDEPEND)
749
#
750
#       $(LIBDIR)/shared:   SHNAME=name
751
#       $(LIBDIR)/shared:   SHBASE=base
752
#       $(LIBDIR)/shared:   $(LIBDIR)/name.dep  \
753
#           $(OBJECTS)
754
#                           
755
#       ifneq "$(findstring $(IFLAG),23)" ""
756
#       -include            "$(LIBDIR)/name.dep"
757
#       endif
758
#
759
#       name_ld += ...
760
#           :
761
#
762
###############################################################################
763
 
764
sub ToolsetSHLD
765
{
289 dpurdie 766
    my( $name, $pArgs, $pObjs, $pLibs, $ver ) = @_;
373 dpurdie 767
    my( $linkname, $soname, $shared, $dbgname, $def, $def_pref, $multi_scan );
4034 dpurdie 768
    my $sosuffix;
769
    my $noVersionedLib = $::ScmCompilerOpts{'NO_VERSIONED_DLLS'};
227 dpurdie 770
 
4034 dpurdie 771
 
227 dpurdie 772
#.. Parse arguments
773
#
774
    foreach $_ ( @$pArgs )
775
    {
776
        if (/^--Def=(.*?)(\,(.*))?$/) {         # Library definition
777
            #
778
            #   Locate the Def file.
779
            #   If it is a generate file so it will be in the SRCS hash
780
            #   Otherwise the user will have to use Src to locate the file
781
            #
782
            $def = MakeSrcResolve($1);
783
            $def_pref = '';
784
            if ( $1 =~ m~\.def$~ ) {
785
                $def_pref = '--version-script='; # Old def file
786
            }
787
        } elsif ( /^--MultiScan/i ) {
788
            $multi_scan = 1;
789
 
790
        } elsif ( /^--NoMultiScan/i ) {
791
            $multi_scan = 0;
792
 
339 dpurdie 793
        } elsif ( /^--SoNameSuffix=(.*)/i ) {
794
            $sosuffix = $1;
795
 
4034 dpurdie 796
        } elsif (/^--NoVersionDll/i) {
797
            $noVersionedLib = 1;
798
 
227 dpurdie 799
        } else {
800
            Message( "SHLD: unknown option $_ -- ignored\n" );
801
        }
802
    }
803
 
4034 dpurdie 804
    #
805
    # Determine the 'soname' in none has been provided
806
    #
807
    $sosuffix = '.' . $ver
808
        unless ( defined $sosuffix );
809
    $sosuffix = ''
810
        if ( $noVersionedLib );
811
 
339 dpurdie 812
#.. Various library names
227 dpurdie 813
#
339 dpurdie 814
    $linkname = "$name\$(GBE_TYPE).$::so";
4034 dpurdie 815
    $shared = $noVersionedLib ? $linkname : "$linkname.$ver";
339 dpurdie 816
    $soname = "$linkname$sosuffix";
4034 dpurdie 817
 
373 dpurdie 818
    my $shared_path = "\$(LIBDIR)/${shared}";
819
    my $dbg_path =  $shared_path . '.dbg';
227 dpurdie 820
 
821
#.. Cleanup rules
822
#
823
#   map     Map file
824
#   ln      Link from LIBDIR to BINDIR
825
#
261 dpurdie 826
    ToolsetGenerate( "\$(LIBDIR)/${name}.map" );
827
    ToolsetGenerate( "\$(LIBDIR)/${shared}" );
339 dpurdie 828
    ToolsetGenerate( "\$(BINDIR)/${soname}" );
373 dpurdie 829
    ToolsetGenerate( $dbg_path );
227 dpurdie 830
 
831
#.. Build rules
832
#
833
#   name        Base name
834
#   shared      Library name, includes GBE_TYPE specification
835
#
836
    my ($io) = ToolsetPrinter::New();
335 dpurdie 837
    my $dep = $io->SetShldTarget($shared);
227 dpurdie 838
 
839
    $io->Label( "Shared library", $name );
339 dpurdie 840
    PackageShlibAddFiles( $name, "\$(LIBDIR)/$shared" );
373 dpurdie 841
    PackageShlibAddFiles( $name, $dbg_path );
4034 dpurdie 842
 
227 dpurdie 843
    $io->Prt( "\$(LIBDIR)/${shared}:\tSHBASE=${name}\n" );
339 dpurdie 844
    $io->Prt( "\$(LIBDIR)/${shared}:\tSHNAME=${soname}\n" );
845
    $io->Prt( "\$(LIBDIR)/${shared}: \\\n\t\t${dep}" );
321 dpurdie 846
    $io->Entry( "", "", " \\\n\t\t", ".$::o", @$pObjs );
227 dpurdie 847
    $io->Prt( "\\\n\t\t$def" ) if($def);
373 dpurdie 848
    $io->Prt( "\n\t\$(SHLD)" );
849
    $io->Prt( "\n\t\$(call LDSTRIP,$shared_path,$dbg_path)\n\n" );
321 dpurdie 850
 
339 dpurdie 851
#
852
#   Create soft links
853
#       'Real Name' to its 'Link Name'
854
#       'Real Name' to 'SoName' in the BINDIR (for testing I think)
855
#       'Real Name' to 'SoName' in the LIBDIR (if different)
856
#
4034 dpurdie 857
    if ( $shared ne $linkname)
858
    {
859
        $io->Label( "Shared library Symbolic Links", $name );
5882 dpurdie 860
        PackageShlibAddFiles( $name, "\$(LIBDIR)/$linkname", 'symlink=1' );
4034 dpurdie 861
        $io->Prt( "\$(LIBDIR)/$linkname:\t\\\n" .
862
                  "\t\t\$(GBE_BINDIR)\\\n" .
863
                  "\t\t\$(LIBDIR)/${shared}\n" .
5882 dpurdie 864
                  "\t\$(AA_PRE)(rm -f \$@; ln -s $shared \$@)\n\n" );
4034 dpurdie 865
    }
866
 
867
    $io->Label( "Shared library BINDIR Symbolic Links", $name );
5882 dpurdie 868
#    PackageShlibAddFiles( $name, "\$(BINDIR)/$soname", 'symlink=1' );
4034 dpurdie 869
    $io->Prt( "\$(BINDIR)/$soname:\t\\\n" .
339 dpurdie 870
              "\t\t\$(GBE_BINDIR)\\\n" .
871
              "\t\t\$(LIBDIR)/${shared}\n" .
4034 dpurdie 872
              "\t\$(AA_PRE)(rm -f \$@; ln -s ../\$(LIBDIR)/$shared \$@)\n\n" );
339 dpurdie 873
 
4034 dpurdie 874
    if ( $soname ne $shared )
339 dpurdie 875
    {
876
        $io->Label( "Shared library SoName Symbolic Links", $name );
5882 dpurdie 877
        PackageShlibAddFiles( $name, "\$(LIBDIR)/$soname", 'symlink=1' );
339 dpurdie 878
        $io->Prt( "\$(LIBDIR)/$soname:\t\\\n" .
879
                  "\t\t\$(GBE_LIBDIR)\\\n" .
880
                  "\t\t\$(LIBDIR)/${shared}\n" .
5882 dpurdie 881
                  "\t\$(AA_PRE)(rm -f \$@; ln -s $shared \$@)\n" );
339 dpurdie 882
    }
883
 
227 dpurdie 884
#.. Linker command file
885
#
886
#       Now the fun part... piecing together a variable $(name_shld)
887
#       which ends up in the command file.
888
#
339 dpurdie 889
    $io->Newline();
227 dpurdie 890
    $io->SetTag( "${name}_shld" );              # command tag
891
    $io->SetTerm( "\n" );
892
 
893
    $io->Label( "Linker commands", $name );     # label
894
 
895
                                                # object list
896
    $io->ObjList( $name, $pObjs, \&ToolsetObjRecipe );
897
 
898
    ToolsetLibStd( $pLibs );                    # push standard libraries
899
 
900
    $io->Cmd( "-Wl,$def_pref$def" ) if ($def);
901
 
902
    $io->Cmd( "-Wl,--start-group" ) if ($multi_scan);
903
    $io->LibList( $name, $pLibs, \&ToolsetLibRecipe );
904
    $io->Cmd( "-Wl,--end-group" ) if ($multi_scan);
905
 
906
    $io->Newline();
907
 
335 dpurdie 908
    #.. Dependency link,
909
    #   Create a library dependency file
910
    #       Create command file to build applicaton dependency list
911
    #       from the list of dependent libraries
912
    #
913
    #       Create makefile directives to include the dependency
914
    #       list into the makefile.
915
    #
916
    $io->DepRules( $pLibs, \&ToolsetLibRecipe, "\$(LIBDIR)/${shared}" );
339 dpurdie 917
    $io->SHLDDEPEND($name, $soname);
227 dpurdie 918
}
919
 
920
 
921
###############################################################################
271 dpurdie 922
# Function        : ToolsetLD
227 dpurdie 923
#
271 dpurdie 924
# Description     : Takes the user options and builds the rules required to
925
#                   link the program 'name'.
227 dpurdie 926
#
271 dpurdie 927
# Inputs          : $name           - base name of the program
928
#                   $pArgs          - Ref to program arguments
929
#                   $pObjs          - Ref to program objects
930
#                   $pLibs          - Ref to program library list
227 dpurdie 931
#
271 dpurdie 932
# Returns         : Nothing
227 dpurdie 933
#
271 dpurdie 934
# Output:         : Rules and recipes to create a program
935
#                       Create program rules and recipes
936
#                       Create linker input script
937
#                       Create library dependency list
938
#                       Include library dependency information
227 dpurdie 939
#
940
sub ToolsetLD
941
{
942
    my( $name, $pArgs, $pObjs, $pLibs ) = @_;
943
    my $static = $::ScmCompilerOpts{'STATIC_PROGS'};
944
    my $multi_scan;
945
 
946
#.. Parse arguments
947
#
948
    foreach $_ ( @$pArgs )
949
    {
950
        if ( m/^--Static$/ ) {
951
            $static = 1;
952
 
953
        } elsif ( m/^--Shared/ ) {
954
            $static = 0;
955
 
956
        } elsif ( /^--MultiScan/i ) {
957
            $multi_scan = 1;
958
 
959
        } elsif ( /^--NoMultiScan/i ) {
960
            $multi_scan = 0;
961
 
962
        } else {
963
            Message( "LD: unknown option $_ -- ignored\n" );
964
        }
965
    }
966
 
271 dpurdie 967
#.. Names of programs and components
968
#
969
    my $base = "\$(BINDIR)/${name}";
970
    my $full = $base . $::exe;
971
    my $map  = $base . '.map';
972
    my $ld  =  $base . '.ld';
373 dpurdie 973
    my $dbg =  $base . '.dbg';
271 dpurdie 974
 
227 dpurdie 975
#.. Cleanup rules
976
#
271 dpurdie 977
    ToolsetGenerate( $ld );
978
    ToolsetGenerate( $map );
373 dpurdie 979
    ToolsetGenerate( $dbg );
227 dpurdie 980
 
981
#.. Build rules
982
#
983
    my ($io) = ToolsetPrinter::New();
335 dpurdie 984
    my $dep = $io->SetLdTarget( $name );
227 dpurdie 985
 
271 dpurdie 986
    $io->Prt( "$full : $dep " );
987
    $io->Entry( "", "", "\\\n\t", ".$::o ", @$pObjs );
373 dpurdie 988
    $io->Prt( "\n\t\$(LD)" );
989
    $io->Prt( "\n\t\$(call LDSTRIP,$full,$dbg)\n\n" );
227 dpurdie 990
 
271 dpurdie 991
 
227 dpurdie 992
#.. Linker command file
993
#
994
#       Now the fun part... piecing together a variable $(name_ld)
995
#       which ends up in the command file.
996
#
997
    $io->SetTag( "${name}_ld" );                # macro tag
998
    $io->SetTerm( "\n" );
999
 
1000
    $io->Label( "Linker commands", $name );     # label
1001
 
1002
    $io->Cmd( "-static" ) if ($static);         # Link as a static program
1003
 
1004
                                                # object list
1005
    $io->ObjList( $name, $pObjs, \&ToolsetObjRecipe );
1006
 
1007
    ToolsetLibStd( $pLibs );                    # push standard libraries
1008
 
1009
                                                # library list
1010
    $io->Cmd( "-Wl,--start-group" ) if ($multi_scan);
1011
    $io->LibList( $name, $pLibs, \&ToolsetLibRecipe );
1012
    $io->Cmd( "-Wl,--end-group" ) if ($multi_scan);
1013
 
5744 dpurdie 1014
    #   Add Compilers sysroot library path
1015
    #   Only required for a 'native' compiler that is not fully installed on the host
1016
    #   ie: The run-time can't locate the required glic components
5796 dpurdie 1017
    if ($GCCRPath)
1018
    {
1019
        $io->Cmd( "-Wl,-rpath=$GCCRPath" );
1020
        $io->Cmd( "-Wl,--dynamic-linker=$GCCRPath/ld-linux.so.2" ) if ($GCCRPath);
1021
    }
5744 dpurdie 1022
 
227 dpurdie 1023
    $io->Newline();
1024
 
335 dpurdie 1025
    #.. Dependency link,
1026
    #   Create a library dependency file
1027
    #       Create command file to build applicaton dependency list
1028
    #       from the list of dependent libraries
1029
    #
1030
    #       Create makefile directives to include the dependency
1031
    #       list into the makefile.
1032
    #
1033
    $io->DepRules( $pLibs, \&ToolsetLibRecipe, $base );
1034
    $io->LDDEPEND();
271 dpurdie 1035
 
1036
#.. Package up the program and other artifacts
1037
#
1038
    PackageProgAddFiles ( $name, $full );
373 dpurdie 1039
    PackageProgAddFiles ( $name, $dbg );
271 dpurdie 1040
 
227 dpurdie 1041
}
1042
 
4778 dpurdie 1043
  #-------------------------------------------------------------------------------
1044
# Function        : ToolsetPostprocess 
1045
#
1046
# Description     : Last chance by the toolset to perform processing
1047
#                   All Directives have been processed
1048
#
1049
#                   If automated unit test are being used,
1050
#                   then we need to post process the results
1051
#
1052
# Inputs          : None
1053
#
1054
# Returns         : 
1055
#
1056
sub ToolsetPostprocess
1057
{
1058
    ToolsetPreprocessTests();
1059
    ToolsetPostprocessTests();
1060
    ToolsetCollateTestResults();
1061
}
227 dpurdie 1062
 
4728 dpurdie 1063
###############################################################################
1064
# Function        : ToolsetPreprocessTests
1065
#
5884 dpurdie 1066
# Description     : Generate $(OBJDIR)/lcov-baseline.info 
1067
#                   Generate full coverage info
4728 dpurdie 1068
#
1069
# Inputs          : None
1070
#
1071
# Returns         : Nothing
1072
#
1073
# Output:         : Rules and recipes to run before unit tests
1074
#
1075
sub ToolsetPreprocessTests
1076
{
1077
    my ($io) = ToolsetPrinter::New();
1078
    if ( $UseGcov && scalar(keys %::OBJSOURCE) > 0 )
1079
    {
5884 dpurdie 1080
        #
1081
        #   Setup Env so that the files created by GCOV are within the package
1082
        #   being created. Elsewise they will be created all over the file 
1083
        #   system in the original location where the external objects were created.
1084
        #
1085
        $io->PrtLn('GCOV_PREFIX := $(abspath $(INTERFACEDIR)/gcov)' );
1086
        $io->PrtLn('GCOV_PREFIX_STRIP := 0' );
1087
        $io->PrtLn('export GCOV_PREFIX GCOV_PREFIX_STRIP' );
1088
        $io->Newline();
1089
 
1090
        #
1091
        #   GCOV_PKGBASE - used to 'extract' coverage artifacts
1092
        #   Used to limit the coverage report to files that are within this package
1093
        #   Ideally it should be the root of the package, but this is not always known
1094
        #   Use the first two path elements of the current package
1095
        #       Really just want to filter out compiler bits
1096
        #     
1097
 
1098
        $io->PrtLn('GCOV_PKGBASE :=  $(subst $(space),/,$(space)$(wordlist 1,2,$(subst /,$(space),$(CURDIR))))' );
1099
        $io->PrtLn('GCOV_VERBOSE :=  $(if $(VERBOSE_OPT),,--quiet)' );
1100
        $io->Newline();
1101
 
4778 dpurdie 1102
        my $ruleName = 'preprocess_gcov_data';
4728 dpurdie 1103
        my $finaldir='$(LOCALDIR)/lcov/$(GBE_PLATFORM)$(GBE_TYPE)';
1104
        my $final=$finaldir . '/lcov-final.info';
1105
 
4778 dpurdie 1106
        ToolsetAddUnitTestPreProcess($ruleName);
1107
        $io->PrtLn('.PHONY: ' . $ruleName );
1108
        $io->PrtLn($ruleName . ':' );
5884 dpurdie 1109
        $io->PrtLn("\t" . '${XX_PRE}$(rm) -f ${GCOV_PREFIX}/$(CURDIR)/$(OBJDIR)/*.gcda' );
1110
        $io->PrtLn("\t" . '${XX_PRE}$(rm) -f $(OBJDIR)/*.gcda' );
4728 dpurdie 1111
        $io->PrtLn("\t" . '${XX_PRE}$(rm) -f ' . $final);
1112
        $io->PrtLn("\t" . '${XX_PRE}lcov'
5884 dpurdie 1113
                        . ' $(GCOV_VERBOSE)'
4835 dpurdie 1114
                        . ' --capture'
1115
                        . ' --initial'
5884 dpurdie 1116
                        . ' --base-directory $(CURDIR)'
4835 dpurdie 1117
                        . ' --directory $(OBJDIR)'
5731 dpurdie 1118
                        . ' --gcov-tool $(GCC_GCOVTOOL)' 
5884 dpurdie 1119
                       . ' --output-file $(OBJDIR)/lcov-baseline.info' );
4778 dpurdie 1120
        $io->Newline();
5884 dpurdie 1121
        ToolsetGenerate( '$(OBJDIR)/lcov-baseline.info' );
4728 dpurdie 1122
    }
1123
}
1124
 
1125
 
1126
###############################################################################
1127
# Function        : ToolsetPostprocessTests
1128
#
5884 dpurdie 1129
# Description     : Merge this sub-components bits into the the final coverage
1130
#                   file in lcov-baseline.info
1131
#                   
1132
#                   Need to locate the .gcda files and place them in the same directory
1133
#                   as the .gcno files that were created during preprocssing
1134
#                   
1135
#                   Then we can add our trace bits into the file coverage file
4728 dpurdie 1136
#
1137
# Inputs          : None
1138
#
1139
# Returns         : Nothing
1140
#
1141
# Output:         : Rules and recipes to run after the unit tests
1142
#
1143
sub ToolsetPostprocessTests
1144
{
1145
    my ($io) = ToolsetPrinter::New();
1146
    if ( $UseGcov && scalar(keys %::OBJSOURCE) > 0 )
1147
    {
4778 dpurdie 1148
        my $ruleName = 'postprocess_gcov_data';
4728 dpurdie 1149
        my $finaldir='$(LOCALDIR)/lcov/$(GBE_PLATFORM)$(GBE_TYPE)';
1150
        my $final=$finaldir . '/lcov-final.info';
1151
 
4778 dpurdie 1152
        ToolsetAddUnitTestPostProcess($ruleName);
1153
 
1154
        $io->PrtLn('.PHONY: ' . $ruleName );
1155
        $io->PrtLn($ruleName . ':' );
5884 dpurdie 1156
        $io->PrtPart("\t" . '$(XX_PRE)if [ -d "${GCOV_PREFIX}/$(CURDIR)/$(OBJDIR)" ]; then' ); 
1157
        $io->PrtPart("\t\t" . 'cd ${GCOV_PREFIX}/$(CURDIR);');
1158
        $io->PrtPart("\t\t" . 'find $(OBJDIR) -name \'*.gcda\' -exec cp --parent {} $(CURDIR) \\; ;');
1159
#        $io->PrtPart("\t" . 'else');
1160
#        $io->PrtPart("\t\t" . 'echo NO .gcda DATA for $(CURDIR);');
1161
        $io->PrtLn  ("\t" . 'fi' );
4728 dpurdie 1162
        $io->PrtLn  ("\t" . '$(XX_PRE)$(mkdir) -p ' . $finaldir);
5884 dpurdie 1163
        $io->PrtPart("\t" . '$(XX_PRE)GCDA_COUNT=$$(find $(OBJDIR) -name "*.gcda" | wc -l);' ); 
1164
        $io->PrtPart("\t" . 'if [ "$${GCDA_COUNT}" -eq "0" ]; then ');
4728 dpurdie 1165
        $io->PrtPart("\t\t" . 'if [ ! -e ' . $final . " ]; then");
1166
        $io->PrtPart("\t\t\t" . '$(cp) $(OBJDIR)/lcov-baseline.info ' . $final . ';');
1167
        $io->PrtPart("\t\t" . 'else');
1168
        $io->PrtPart("\t\t\t" . 'lcov'
5884 dpurdie 1169
                          . ' $(GCOV_VERBOSE)'
4835 dpurdie 1170
                          . $LcovExplicitBranch
4728 dpurdie 1171
                          . ' --add-tracefile $(OBJDIR)/lcov-baseline.info'
1172
                          . ' --add-tracefile ' . $final
5731 dpurdie 1173
                          . ' --gcov-tool $(GCC_GCOVTOOL)' 
4728 dpurdie 1174
                          . ' --output-file $(OBJDIR)/lcov-merge.info'
1175
                          . ';'); 
1176
        $io->PrtPart("\t\t\t" . '$(rm) -f ' . $final . ';');
1177
        $io->PrtPart("\t\t\t" . '$(mv) $(OBJDIR)/lcov-merge.info ' . $final . ';');
1178
        $io->PrtPart("\t\t" . 'fi' . ';');
1179
        $io->PrtPart("\t" . 'else');
1180
        $io->PrtPart("\t\t" . 'lcov'
5884 dpurdie 1181
                        . ' $(GCOV_VERBOSE)'
1182
                        . $LcovExplicitBranch
4728 dpurdie 1183
                        . ' --capture'
5884 dpurdie 1184
                        . ' --base-directory $(CURDIR)'
4728 dpurdie 1185
                        . ' --directory $(OBJDIR)'
5731 dpurdie 1186
                        . ' --gcov-tool $(GCC_GCOVTOOL)' 
4728 dpurdie 1187
                        . ' --output-file $(OBJDIR)/lcov-capture.info' 
1188
                        . ';'); 
1189
        $io->PrtPart("\t\t" . 'if [ ! -e ' . $final . " ]; then");
1190
        $io->PrtPart("\t\t\t" . 'lcov'
5884 dpurdie 1191
                          . ' $(GCOV_VERBOSE)'
4835 dpurdie 1192
                          . $LcovExplicitBranch
4728 dpurdie 1193
                          . ' --add-tracefile $(OBJDIR)/lcov-baseline.info'
5884 dpurdie 1194
                          . ' --add-tracefile $(OBJDIR)/lcov-capture.info'
5731 dpurdie 1195
                          . ' --gcov-tool $(GCC_GCOVTOOL)' 
4728 dpurdie 1196
                          . ' --output-file ' .  $final
1197
                          . ';'); 
1198
        $io->PrtPart("\t\t" . 'else');
1199
        $io->PrtPart("\t\t\t" . 'lcov'
5884 dpurdie 1200
                          . ' $(GCOV_VERBOSE)'
4835 dpurdie 1201
                          . $LcovExplicitBranch
4728 dpurdie 1202
                          . ' --add-tracefile $(OBJDIR)/lcov-baseline.info'
5884 dpurdie 1203
                          . ' --add-tracefile $(OBJDIR)/lcov-capture.info'
4728 dpurdie 1204
                          . ' --add-tracefile ' . $final
5731 dpurdie 1205
                          . ' --gcov-tool $(GCC_GCOVTOOL)' 
4728 dpurdie 1206
                          . ' --output-file $(OBJDIR)/lcov-merge.info'
1207
                          . ';'); 
1208
        $io->PrtPart("\t\t\t" . '$(rm) -f ' . $final . ';');
1209
        $io->PrtPart("\t\t\t" . '$(mv) $(OBJDIR)/lcov-merge.info ' . $final . ';');
1210
        $io->PrtPart("\t\t" . 'fi' . ';');
1211
        $io->PrtLn  ("\t" . 'fi');
4778 dpurdie 1212
        $io->Newline();
5817 dpurdie 1213
 
1214
        ToolsetGenerate ('$(OBJDIR)/lcov-capture.info' );
1215
        ToolsetGenerate ($final);
1216
 
4728 dpurdie 1217
    }
1218
}
1219
 
1220
 
1221
###############################################################################
1222
# Function        : ToolsetCollateTestResults
1223
#
5884 dpurdie 1224
# Description     : Process the lcov-final.info by
1225
#                       Extract parts generated by files in this package
1226
#                       Remove parts generated by files in the interface directory
1227
#                           They are the results of a 'BuildPkgArchive'
4728 dpurdie 1228
#
1229
# Inputs          : None
1230
#
1231
# Returns         : Nothing
1232
#
1233
# Output:         : Rules and recipes to run after unit test result 
1234
#                   postprocessing.
1235
#
1236
sub ToolsetCollateTestResults
1237
{
1238
    my ($io) = ToolsetPrinter::New();
1239
    if ( $UseGcov && scalar(keys %::OBJSOURCE) > 0 )
1240
    {
4778 dpurdie 1241
        my $ruleName = 'collate_gcov_results';
5884 dpurdie 1242
        my $finaldir = '$(LOCALDIR)/lcov/$(GBE_PLATFORM)$(GBE_TYPE)';
1243
        my $final     = $finaldir . '/lcov-final.info';
5885 dpurdie 1244
        my $finalTmp  = $finaldir . '/lcov-extracted.info';
1245
        my $finalTmp1 = $finaldir . '/lcov-filtered.info';
4778 dpurdie 1246
 
5884 dpurdie 1247
        ToolsetGenerate ( $final );
1248
        ToolsetGenerate ( $finalTmp );
1249
        ToolsetGenerate ( $finalTmp1 );
1250
 
4778 dpurdie 1251
        ToolsetAddUnitTestCollateProcess($ruleName);
4728 dpurdie 1252
 
1253
        my $reportdir='$(PKGDIR)/lcov/$(GBE_PLATFORM)$(GBE_TYPE)';
1254
        my $reportindex=$reportdir . '/index.html';
4778 dpurdie 1255
        $io->PrtLn('.PHONY: ' . $ruleName );
1256
        $io->PrtLn($ruleName . ': ' . $reportindex);
5884 dpurdie 1257
 
4728 dpurdie 1258
        $io->Newline();
1259
        $io->PrtLn($reportindex . ': ' . $final);
5884 dpurdie 1260
        $io->PrtPart("\t" . 'lcov'
1261
                        . ' $(GCOV_VERBOSE)'
1262
                        . $LcovExplicitBranch
1263
                        . ' --extract '. $final .' "$(GCOV_PKGBASE)/*"'
1264
                        . ' --gcov-tool $(GCC_GCOVTOOL)' 
1265
                        . ' --output-file ' . $finalTmp
1266
                        . ';'); 
1267
        $io->PrtPart("\t" . 'lcov'
1268
                        . ' $(GCOV_VERBOSE)'
1269
                        . $LcovExplicitBranch
1270
                        . ' --remove '. $finalTmp .' "$(abspath $(INTERFACEDIR))/*"'
1271
                        . ' --gcov-tool $(GCC_GCOVTOOL)' 
1272
                        . ' --output-file ' .$finalTmp1
1273
                        . ';'); 
4728 dpurdie 1274
        $io->PrtLn("\t" . 'genhtml'
5884 dpurdie 1275
                      . ' $(GCOV_VERBOSE)'
4728 dpurdie 1276
                      . ' --frames'
1277
                      . ' --show-details'
1278
                      . ' --function-coverage'
1279
                      . ' --branch-coverage'
1280
                      . ' --output-directory ' . $reportdir
1281
                      . ' --legend'
5885 dpurdie 1282
                      . ' --demangle-cpp' 
1283
                      . ' --title "$(GBE_PBASE) $(BUILDVER)"'
5884 dpurdie 1284
                      . ' ' . $finalTmp1);
4778 dpurdie 1285
        $io->Newline();
4728 dpurdie 1286
    }
1287
}
1288
 
1289
 
1290
###############################################################################
1291
#   ToolsetARLINT( $name, \@args, \@objs )
1292
#       This subroutine takes the user options and builds the rules
1293
#       required to lint the static library 'name'.
1294
#
1295
#   Arguments:
1296
#       --xxx                   No arguments currently defined
1297
#
1298
#   Output:
1299
#       [ $(LIBDIR)/name$_lint:   .... ]
1300
#           $(ARLINT)
1301
#
1302
###############################################################################
1303
 
1304
sub ToolsetARLINT
1305
{
1306
    if ( $UseCppcheck )
1307
    {
1308
        CppcheckAR( @_ );
1309
    }
1310
}
1311
 
1312
 
1313
###############################################################################
1314
#   ToolsetSHLDLINT $name, \@args, \@objs, \@libraries )
1315
#       This subroutine takes the user options and builds the rules
1316
#       required to lint the shared library 'name'.
1317
#
1318
#   Arguments:
1319
#       (none)
1320
#
1321
#   Output:
1322
#       [ $(LIBDIR)/$name_lint:   .... ]
1323
#           $(SHLIBLINT)
1324
#
1325
###############################################################################
1326
 
1327
sub ToolsetSHLDLINT
1328
{
1329
    if ( $UseCppcheck )
1330
    {
1331
        CppcheckSHLD( @_ );
1332
    }
1333
}
1334
 
1335
 
1336
###############################################################################
1337
#   ToolsetLD( $name, \@args, \@objs, \@libraries, \@csrc, \@cxxsrc )
1338
#       This subroutine takes the user options and builds the rules
1339
#       required to lint the program 'name'.
1340
#
1341
#   Arguments:
1342
#       (none)
1343
#
1344
#   Output:
1345
#       [ $(BINDIR)/$name_lint:   .... ]
1346
#           $(LDLINT)
1347
#
1348
###############################################################################
1349
 
1350
sub ToolsetLDLINT
1351
{
1352
    if ( $UseCppcheck )
1353
    {
1354
        CppcheckLD( @_ );
1355
    }
1356
}
1357
 
227 dpurdie 1358
########################################################################
1359
#
1360
#   Push standard "system" libraries. This is a helper function
1361
#   used within this toolset.
1362
#
1363
#   Arguments:
1364
#       $plib       Reference to library array.
1365
#
1366
########################################################################
1367
 
1368
sub ToolsetLibStd
1369
{
1370
}
1371
 
1372
 
1373
########################################################################
1374
#
1375
#   Generate a linker object recipe.  This is a helper function used 
1376
#   within this toolset.
1377
#
1378
#   Arguments:
1379
#       $io         I/O stream
1380
#
1381
#       $target     Name of the target
1382
#
1383
#       $obj        Library specification
1384
#
1385
########################################################################
1386
 
1387
sub ToolsetObjRecipe
1388
{
1389
    my ($io, $target, $obj) = @_;
1390
 
1391
    $io->Cmd( "\$(strip $obj).$::o" );
1392
}
1393
 
1394
 
1395
###############################################################################
1396
#
1397
#   Parse a linker lib list
1398
#   This is a helper function used within this toolset
1399
#
1400
#   Arguments:
1401
#       $target     Name of the target
1402
#
1403
#       $lib        Library specification
1404
#
1405
#       $tag        Tag (user specified)
1406
#
1407
#       $dp         If building a depend list, the full target name.
1408
#
1409
###############################################################################
1410
 
1411
sub ToolsetLibRecipe
1412
{
1413
    my ($io, $target, $lib, $dp) = @_;
1414
 
1415
    if ( ! defined($dp) ) {                     # linker
1416
        $lib =~ s/^lib//;                       # .. remove leading 'lib'
1417
        $io->Cmd( "-l$lib" );
1418
 
1419
    } else {                                    # depend
1420
        $io->Cmd( "$dp:\t@(vlib2,$lib,GCC_LIB)" );
1421
 
1422
    }
1423
}
1424
 
1425
#.. Successful termination
1426
1;
1427