Subversion Repositories DevTools

Rev

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

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