Subversion Repositories DevTools

Rev

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

Rev Author Line No. Line
303 dpurdie 1
#
2
# Module name   : vcwce
3
# Module type   : Makefile system
4
# Compiler(s)   : ANSI C
5
# Environment(s): WCE
6
#
7
# Description:
8
#   Visual C/C++ for WCE
9
#
10
#............................................................................#
11
 
12
use strict;
13
use warnings;
14
 
15
#
16
#   Global data
17
#
18
my $pdb_file = "\$(GBE_PBASE)";
19
my $pdb_first_lib;
20
my $target_file_lib;
21
my $target_file_dll;
22
my $target_file_exe;
23
my $pdb_none;
343 dpurdie 24
my $toolset_name = 'vcwce';                           # Toolset name : Error reporting
303 dpurdie 25
 
26
##############################################################################
27
#   Toolchain information
335 dpurdie 28
#   Abstract out minor toolchain differences into a data structure
303 dpurdie 29
#
30
my $toolchain_info;
31
my %ToolChainData =
32
    (
33
        'EVC4'      =>  {  'def'        => 'vcwce.def' ,
34
                           'initDef'    => 'vcembedded',
35
                           'wceroot'    => 'Microsoft eMbedded C++ 4.0',
343 dpurdie 36
                           'buildcmd'   => 'evc =DSW= /make =TYPE= /use_env /CEConfig="=CEPLATFORM=" /out =LOG=',
37
                           'cleancmd'   => 'evc =DSW= /make =TYPE= /clean /use_env /CEConfig="=CEPLATFORM="',
303 dpurdie 38
                           'tmp'        => 'vc60',
39
                           'VSCOMPILER' => '1',
343 dpurdie 40
                           'def_targets' => [ 'ALL - RELEASE','ALL - DEBUG' ],
303 dpurdie 41
                           },
42
 
43
 
44
        'VS2005'    =>  {  'def'        => 'vcembedded2005.def' ,
45
                           'initDef'    => 'vcembedded',
46
                           'buildcmd'   => 'devenv =DSW= /build =TYPE= /useenv /out =LOG=' ,
47
                           'cleancmd'   => 'devenv =DSW= /clean =TYPE= /useenv' ,
48
                           'tmp'        => 'vc80',
49
                           'VSCOMPILER' => '2',
50
 
51
                           'wceroot'    => 'Microsoft Visual Studio 8/VC/ce',
52
                           'includes'   => [    '$(WCEROOT)/include',
53
                                                '$(WCEROOT)/atlmfc/include',
54
                                           ],
55
                           'libs'       => [    '$(WCEROOT)/lib/$(WCE_TARGETCPU)',
56
                                                '$(WCEROOT)/atlmfc/lib/$(WCE_TARGETCPU)',
57
                                           ],
357 dpurdie 58
                           'hex_WCEVersion' => 1,
303 dpurdie 59
                           },
60
 
61
    );
62
 
63
 
64
##############################################################################
65
#   ToolsetInit()
66
#       Runtime initialisation
67
#
68
##############################################################################
69
 
357 dpurdie 70
my( $WCEVersion,$WCEVersionTool ) = "";
303 dpurdie 71
my( $WCESubsystem )             = "";
72
my( $WCEPlatform )              = "";
73
my( $WCEPlatformDefine )        = "";
74
my( $WCEPlatformClean )         = "";
75
my( $WCETargetCPU )             = "";
76
my( $WCEHostCPU )               = "";
77
my( $WCEToolchain )             = "";
78
 
79
ToolsetInit();
80
 
81
sub ToolsetInit
82
{
83
    my( $wceroot, $sdkroot );
84
    my( $compiler, $linker, $vstool );
85
    my( @defines ) = ();
86
    my( @cflags, @cflags_debug, @cflags_prod ) = ();
87
    my( @libflags, @ldflags, @ldflags_debug, @ldflags_prod ) = ();
88
    my $is_vs2005;
317 dpurdie 89
    my $default_ehandling = undef;
355 dpurdie 90
    my @pDefines;
303 dpurdie 91
 
92
#.. Standard.rul requirements
93
#
94
    $::s = "asm";
95
    $::o = "obj";
96
    $::a = "lib";
97
    $::so = "dll";
98
    $::exe = ".exe";
99
 
100
#.. Toolset configuration
101
#
102
    $::ScmToolsetVersion = "1.0.0";             # our version
103
    $::ScmToolsetGenerate = 0;                  # generate optional
335 dpurdie 104
    $::ScmToolsetProgDependancies = 0;          # handle Prog dependancies myself
303 dpurdie 105
 
106
#.. Parse arguments
107
#
343 dpurdie 108
    Debug( "$toolset_name(ToolsetArgs=@::ScmToolsetArgs)" );
303 dpurdie 109
 
110
    foreach ( @::ScmToolsetArgs ) {
343 dpurdie 111
        Message( "$toolset_name toolset: unknown option $_ -- ignored\n" );
303 dpurdie 112
    }
113
 
343 dpurdie 114
    Debug( "$toolset_name(PlatformArgs=@::ScmPlatformArgs)" );
303 dpurdie 115
 
116
    foreach ( @::ScmPlatformArgs ) {
117
        if (/^--Version=(.*)/) {                # OS Version
118
            $WCEVersion     = "$1";
119
 
120
        } elsif (/^--SDK=(.*)/) {               # SDK
121
            $WCEPlatform    = "$1";
122
 
123
        } elsif (/^--Target=(.*)/) {            # CPU
124
            $WCETargetCPU   = "$1";
125
 
126
        } elsif (/^--Host=(.*)/) {              # Emulator host CPU
127
            $WCEHostCPU     = "$1";
128
 
129
        } elsif (/^--Toolchain=(.*)/) {         # Toolchain
130
            $WCEToolchain   = "$1";
131
 
132
        } elsif (/^--product=(.*)/) {           # GBE product
133
 
134
        } elsif (/^--NoDinkumware/) {           # Deprecated switch
355 dpurdie 135
 
136
        } elsif (/^--Define=(.*)/ ) {
137
            push @pDefines, '-D' . $1;
138
 
303 dpurdie 139
        } else {
343 dpurdie 140
            Message( "$toolset_name toolset: unknown platform argument $_ -- ignored\n" );
303 dpurdie 141
        }
142
    }
143
 
144
#.. Select toolchain, based on targetCPU
145
#       1) EVC            - As provided via Embedded Visual C++
146
#       2) VS2005         - As provided via VS2005
147
#
148
    $toolchain_info = $ToolChainData{$WCEToolchain};
149
    Error( "Unknown Toolchain: $WCEToolchain" ) unless ( defined $toolchain_info );
150
    $is_vs2005 = ($toolchain_info->{'VSCOMPILER'} == 2);
151
 
152
#
153
#   The following table shows the processors that eMbedded Visual C++
154
#   currently supports.
155
#
156
#   ARM         ARMV4, ARMV4I, ARMV4T
157
#   MIPS        MIPSII, MIPSII_FP, MIPSIV, MIPSIV_FP, MIPS16
158
#   Hitachi     SH3, SH4
159
#   x86         x86, x86 emulation
160
#..
343 dpurdie 161
    Error ("TOOLSET/$toolset_name - Version undefined")
303 dpurdie 162
        if ($WCEVersion eq "");
163
 
343 dpurdie 164
    Error ("TOOLSET/$toolset_name - SDK undefined")
303 dpurdie 165
        if ($WCEPlatform eq "");
166
 
343 dpurdie 167
    Error ("TOOLSET/$toolset_name - TargetCPU undefined")
303 dpurdie 168
        if ($WCETargetCPU eq "");
169
 
343 dpurdie 170
    Error ("TOOLSET/$toolset_name - HostCPU undefined")
303 dpurdie 171
        if ($WCEPlatform eq "emulator" && $WCEHostCPU eq "");
172
 
343 dpurdie 173
    Error ("TOOLSET/$toolset_name - Toolchain undefined")
303 dpurdie 174
        unless ( $WCEToolchain );
175
 
176
 
177
# .. Generate CE Platform definition based on the selected SDK
178
#    The following is a list of known defintions for some SDKs
179
#    In the EVC studio these are $(CePlatform)
180
#..
181
    my %PlatformSDKDefinitions =
182
    (
183
        'H/PC 2000'         => 'WIN32_PLATFORM_HPC2000',
184
        'H/PC Pro 2.11'     => 'WIN32_PLATFORM_HPCPRO',
185
        'Pocket PC'         => 'WIN32_PLATFORM_PSPC',
186
        'Pocket PC 2002'    => 'WIN32_PLATFORM_PSPC=310',
187
        'POCKET PC 2003'    => 'WIN32_PLATFORM_PSPC=400',
188
        'Smartphone 2002'   => 'WIN32_PLATFORM_WFSP=100',
189
        'IT-3000'           => 'WCE_PLATFORM_PX780J_ARMV4I',
190
        'PCM7220'           => 'WCE_PLATFORM_SOCERXS',
191
        'ADVANTECH_X86_420' => 'WCE_PLATFORM_ADVANTECH_X86_420',
192
        'SOM_4450_2'        => 'WCE_PLATFORM_SOM_4450_2',
193
        'adv_som_4455_wlan' => 'WCE_PLATFORM_adv_som_4455_wlan',
194
        'PsionTeklogixCE420'=> 'WCE_PLATFORM_STANDARDSDK',
195
        'PsionTeklogixCE500'=> 'WCE_PLATFORM_STANDARDSDK',
196
        'PA961'             => 'WCE_PLATFORM_PA961',
197
        'PA962'             => 'WCE_PLATFORM_PA962',
198
        'PA962 WINCE 500'   => 'WCE_PLATFORM_PA962',
355 dpurdie 199
        'M81B_SDK'          => 'WCE_PLATFORM_M81B',     # Just made this one up
303 dpurdie 200
    );
201
 
202
    $WCEPlatformDefine = $PlatformSDKDefinitions{$WCEPlatform};
203
 
343 dpurdie 204
    Error ("TOOLSET/$toolset_name - SDK not defined. Extend table",
303 dpurdie 205
           "SDK: $WCEPlatform" )
206
        unless ( defined $WCEPlatformDefine );
207
 
208
    $WCEPlatformClean = $WCEPlatform;
209
    $WCEPlatformClean =~ s/\s/_/g;
210
 
211
    $WCESubsystem = "windowsce," . int($WCEVersion/100) . "." . $WCEVersion%100
212
        if ( !defined($WCESubsystem) || $WCESubsystem eq "" );
213
 
214
        push( @ldflags,     '-debug:full' ) unless ($is_vs2005);
215
        push( @ldflags,     '-debug' )      if ($is_vs2005);
216
 
217
#.. Select toolchain info , based on targetCPU
218
 
219
    if ( $WCETargetCPU eq "armv4" ) {
220
        $compiler           = "clarm";
221
        $linker             = "link";
222
        $vstool             = "x86_arm";
317 dpurdie 223
        $default_ehandling  = 1;
303 dpurdie 224
 
225
        @defines            = ( '-DARM', '-D_ARM_', '-DARMV4' );
226
 
317 dpurdie 227
        @cflags             = ( '-QRarch4' );
303 dpurdie 228
        @cflags             = ( '/GS-' )           if ($is_vs2005);
229
        @cflags_debug       = ( '-M$(CECrtDebug)' )unless ($is_vs2005);
230
        @cflags_prod        = ( '-M$(CECrtMT)' )   unless ($is_vs2005);
231
 
232
        push( @ldflags,     '-base:0x00010000' );
233
        push( @ldflags,     '-stack:0x10000,0x1000' );
234
        push( @ldflags,     '-entry:WinMainCRTStartup' );
235
        push( @ldflags,     '$(CENoDefaultLib)' );
236
        push( @ldflags,     '-Subsystem:$(CESubsystem)' );
237
        push( @ldflags,     '-align:4096' );
238
        push( @ldflags,     '-MACHINE:ARM' );
239
        push( @ldflags,     'commctrl.lib' );
240
        push( @ldflags,     'coredll.lib' );
241
        push( @ldflags,     'aygshell.lib' );
242
        push( @ldflags,     '$(CEx86Corelibc)' ) if ($is_vs2005);
243
 
244
        push( @libflags,    '-MACHINE:ARM' );
245
 
246
    } elsif ( $WCETargetCPU eq "armv4i" ) {
247
        $compiler           = "clarm";
248
        $linker             = "link";
249
        $vstool             = "x86_arm";
250
 
251
        @defines            = ( '-DARM', '-D_ARM_', '-DARMV4I' );
252
 
253
        @cflags             = ( '/QRarch4T' );
254
        @cflags             = ( '/QRinterwork-return' );
255
        @cflags             = ( '/GS-' )           if ($is_vs2005);
256
        @cflags_debug       = ( '-M$(CECrtDebug)' )unless ($is_vs2005);
257
        @cflags_prod        = ( '-M$(CECrtMT)' )   unless ($is_vs2005);
258
 
259
        push( @ldflags,     '-base:0x00010000' );
260
        push( @ldflags,     '-stack:0x10000,0x1000' );
261
        push( @ldflags,     '-entry:WinMainCRTStartup' );
262
        push( @ldflags,     '$(CENoDefaultLib)' );
263
        push( @ldflags,     '-nodefaultlib:oldnames.lib' ) if (1);
264
        push( @ldflags,     '-Subsystem:$(CESubsystem)' );
265
        push( @ldflags,     '-MACHINE:THUMB' );
266
        push( @ldflags,     'commctrl.lib' );
267
        push( @ldflags,     'coredll.lib' );
268
        push( @ldflags,     '$(CEx86Corelibc)' ) if ($is_vs2005);
269
 
270
        push( @libflags,    '-MACHINE:THUMB' );
271
 
272
 
273
    } elsif ( $WCETargetCPU eq "armv4t" ) {
274
        $compiler           = "clthumb";
275
        $linker             = "link";
276
        $vstool             = "x86_arm";
277
 
278
        @cflags             = ( '/QRarch4t' );
279
        @defines            = ( '-DARM', '-D_ARM_', '-DARMV4T' );
280
 
281
    } elsif ( $WCETargetCPU eq "mips16" ) {
282
        $compiler           = "clmips";
283
        $linker             = "link";
284
        $vstool             = "x86_mips";
285
 
286
        @cflags             = ( '/QMmips16' );
287
        @defines            = ( '-DMIPS', '-D_MIPS_' );
288
 
289
    } elsif ( $WCETargetCPU eq "mips16ii" ) {
290
        $compiler           = "clmips";
291
        $linker             = "link";
292
        $vstool             = "x86_mips";
293
 
294
        @cflags             = ( '/QMmips16' );
295
        @defines            = ( '-DMIPS', '-D_MIPS_' );
296
 
297
    } elsif ( $WCETargetCPU eq "mipsii_fp" ) {
298
        $compiler           = "clmips";
299
        $linker             = "link";
300
 
301
        @cflags             = ( '/QMFWCE' );
302
        @defines            = ( '-DMIPS', '-D_MIPS_' );
303
 
304
    } elsif ( $WCETargetCPU eq "mipsiv" ) {
305
        $compiler           = "clmips";
306
        $linker             = "link";
307
        $vstool             = "x86_mips";
308
 
309
        @defines            = ( '-DMIPS', '-D_MIPS_' );
310
 
311
    } elsif ( $WCETargetCPU eq "mipsiv_fp" ) {
312
        $compiler           = "clmips";
313
        $linker             = "link";
314
 
315
        @cflags             = ( '/QMFWCE' );
316
        @defines            = ( '-DMIPS', '-D_MIPS_' );
317
 
318
    } elsif ( $WCETargetCPU eq "sh3" ) {
319
        if ( $WCEVersion >= 400 ) {             # SDK specific
320
            $compiler       = "clsh";
321
        } else {
322
            $compiler       = "shcl";
323
        }
324
        $linker             = "link";
325
        $vstool             = "x86_sh";
326
 
327
        @cflags             = ( '-Qsh3' );
328
        @defines            = ( '-DSHx', '-DSH3', '-D_SH3_' );
329
 
330
    } elsif ( $WCETargetCPU eq "sh4" ) {
331
        if ( $WCEVersion >= 400 ) {             # SDK specific
332
            $compiler       = "clsh";
333
        } else {
334
            $compiler       = "shcl";
335
        }
336
        $linker             = "link";
337
        $vstool             = "x86_sh";
338
 
339
        @cflags             = ( '-Qsh4' );
340
        @defines            = ( '-DSHx', '-DSH4', '-D_SH4_' );
341
 
342
    } elsif ( $WCETargetCPU eq "x86" ) {
343
        $compiler           = "cl";
344
        $linker             = "link";
345
        $vstool             = "x86_cex86";
346
 
347
        @cflags             = ( '-Gs8192', '-GF' );
348
        @defines            = ( '-D_X86_', '-Dx86', '-D_i386_' );
349
 
350
        push( @ldflags, '-section:.shared,rws' );
351
        push( @ldflags, '-base:0x00100000' );
352
        push( @ldflags, '-stack:0x10000,0x1000' );
353
        push( @ldflags, '-entry:WinMainCRTStartup' );
354
        push( @ldflags, '-Subsystem:$(CESubsystem)' );
355
        push( @ldflags, '-MACHINE:IX86' );
356
        push( @ldflags, '$(CENoDefaultLib)' );
357
        push( @ldflags, '-nodefaultlib:oldnames.lib' );
358
        push( @ldflags, '$(CEx86Corelibc)' );
359
        push( @ldflags, 'coredll.lib' );
360
        push( @ldflags, 'commctrl.lib' );
361
        push( @ldflags, 'aygshell.lib' );
362
 
363
        push( @libflags,'-MACHINE:IX86' );
364
 
365
    } elsif ( $WCETargetCPU eq "emulator" ) {
366
 
367
        if ( $WCEHostCPU eq "x86" ) {
368
            $compiler       = "cl";
369
            $linker         = "link";
370
            $vstool         = "x86_cex86";
317 dpurdie 371
            $default_ehandling  = 1;
303 dpurdie 372
 
373
            @defines        = ( '-D_X86_', '-Dx86', '-D_i386_' );
374
 
317 dpurdie 375
            @cflags         = ( '-Gs8192', '-GF' );
303 dpurdie 376
 
377
            push( @ldflags, '-base:0x00010000' );
378
            push( @ldflags, '-stack:0x10000,0x1000' );
379
            push( @ldflags, '-entry:WinMainCRTStartup' );
380
            push( @ldflags, '-Subsystem:$(CESubsystem)' );
381
            push( @ldflags, '-MACHINE:IX86' );
382
            push( @ldflags, '$(CENoDefaultLib)' );
383
            push( @ldflags, '-nodefaultlib:oldnames.lib' );
384
            push( @ldflags, '$(CEx86Corelibc)' );
385
            push( @ldflags, 'commctrl.lib' );
386
            push( @ldflags, 'coredll.lib' );
387
            push( @ldflags, 'aygshell.lib' );
388
 
389
            push( @libflags,'-MACHINE:IX86' );
390
 
391
        } else {
343 dpurdie 392
            Error ("TOOLSET/$toolset_name - unknown HostCPU '$WCEHostCPU'");
303 dpurdie 393
        }
394
 
395
    } else {
343 dpurdie 396
        Error ("TOOLSET/$toolset_name - unknown TargetCPU '$WCETargetCPU'");
303 dpurdie 397
    }
398
 
355 dpurdie 399
    #
400
    #   Append any platform specific definitions
401
    #
402
    push @defines, @pDefines;
403
 
303 dpurdie 404
#.. Define eMebbed C/C+ environment
405
#
406
 
407
    #
408
    #   Determine the toolchain root
409
    #   Currently these are within ProgramFiles
410
    #
411
    $wceroot = $toolchain_info->{'wceroot'};
412
 
413
    #
357 dpurdie 414
    #   The VS2005 toolchain uses a hex value for WCEVersion
415
    #
416
    $WCEVersionTool = $WCEVersion;
417
    $WCEVersionTool = '0X' . $WCEVersion if ( $toolchain_info->{'hex_WCEVersion'} );
418
 
419
 
420
    #
303 dpurdie 421
    #   Determine SDK root
422
    #   Currently these are well known
423
    #
424
    $sdkroot = 'Windows CE Tools/wce'.$WCEVersion.'/'.$WCEPlatform;
425
 
426
    Debug( "\twceroot           = $wceroot" );
427
    Debug( "\tsdkroot           = $sdkroot" );
428
    Debug( "\tWCEVersion        = $WCEVersion" );
429
    Debug( "\tWCESubsystem      = $WCESubsystem" );
430
    Debug( "\tWCEPlatform       = $WCEPlatform" );
431
    Debug( "\tWCEPlatformDefine = $WCEPlatformDefine" );
432
    Debug( "\tWCEPlatformClean  = $WCEPlatformClean" );
433
    Debug( "\tWCETargetCPU      = $WCETargetCPU" );
434
    Debug( "\tWCEHostCPU        = $WCEHostCPU" );
435
    Debug( "\tWCEToolchain      = $WCEToolchain" );
436
 
437
    PlatformDefine( "
438
#################################################
439
# Default paths, toolchain and flags
440
#
441
#..
442
 
443
PROGRAMFILES        ?= C:/Program Files
444
 
445
ifndef WCEROOT
446
WCEROOT		:= \$(PROGRAMFILES)/" . $wceroot ."
447
export WCEROOT
448
endif
449
 
450
ifndef SDKROOT
451
SDKROOT		:= \$(PROGRAMFILES)/" . $sdkroot ."
452
export SDKROOT
453
endif
454
 
455
WCE_VSTOOL           := $vstool
357 dpurdie 456
WCE_VERSION          := $WCEVersionTool
303 dpurdie 457
WCE_SUBSYSTEM        := $WCESubsystem
458
WCE_PLATFORM         := $WCEPlatform
459
WCE_PLATFORM_SDK_DEF := $WCEPlatformDefine
460
WCE_PLATFORM2        := $WCEPlatformClean
461
WCE_TARGETCPU        := $WCETargetCPU
462
WCE_HOSTCPU	         := $WCEHostCPU
463
 
464
CESubsystem          := \$(WCE_SUBSYSTEM)
465
CEVersion            := \$(WCE_VERSION)
466
CEPlatform           := \$(WCE_PLATFORM)
467
");
468
 
469
if ( $WCEVersion < 201 ) {
470
    PlatformDefine( '
471
CECrtDebug	:= Ld
472
CECrtMT		:= T
473
CENoDefaultLib	:= \
474
		-nodefaultlib:corelibc.lib
475
CEx86Corelibc	:=
476
');
477
} else {
478
    PlatformDefine( '
479
CECrtDebug	:= C
480
CECrtMT		:= C
481
CENoDefaultLib	:= \\
482
		-nodefaultlib:libc.lib\
483
		-nodefaultlib:libcd.lib\
484
		-nodefaultlib:libcmt.lib\
485
		-nodefaultlib:libcmtd.lib\
486
		-nodefaultlib:msvcrt.lib\
487
		-nodefaultlib:msvcrtd.lib
488
CEx86Corelibc	:= corelibc.lib
489
' );
490
}
491
 
307 dpurdie 492
if ( $is_vs2005 )
493
{
494
    PlatformDefine( '
495
CENoDefaultLib	+= \\
496
		-nodefaultlib:secchk.lib\
497
		-nodefaultlib:ccrtrtti.lib
498
' );
499
}
500
 
303 dpurdie 501
#
502
#   WinCe development platform specifics
503
#       Encode Toolset paths as they contain spaces
504
#       These will be decoded later
505
#
506
PlatformEntry( "vc_includes\t=", "\n", "\\\n\t" . '$(call encodepath,', ')', @{$toolchain_info->{'includes'}} );
507
PlatformEntry( "vc_libs\t="    , "\n", "\\\n\t" . '$(call encodepath,', ')', @{$toolchain_info->{'libs'}} );
508
 
509
    PlatformDefine( "WCE_EMULATOR\t".   ":= 1" )
510
        if ( $WCETargetCPU eq "emulator" );
511
 
512
    PlatformEntry( "WCE_DEFINES\t=",    "\n", "\\\n\t", "", @defines )
513
        if ( scalar @defines );
514
 
515
    PlatformEntry( "WCE_CFLAGS\t=",     "\n", "\\\n\t", "", @cflags )
516
        if ( scalar @cflags );
517
 
518
    PlatformEntry( "WCE_CFLAGSD\t=",    "\n", "\\\n\t", "", @cflags_debug )
519
        if ( scalar @cflags_debug );
520
 
521
    PlatformEntry( "WCE_CFLAGSP\t=",    "\n", "\\\n\t", "", @cflags_prod )
522
        if ( scalar @cflags_prod );
523
 
524
    PlatformEntry( "WCE_LDFLAGS\t=",    "\n", "\\\n\t", "", @ldflags )
525
        if ( scalar @ldflags );
526
 
527
    PlatformEntry( "WCE_LIBFLAGS\t=",    "\n", "\\\n\t", "", @libflags )
528
        if ( scalar @libflags );
529
 
530
    PlatformEntry( "WCE_LDFLAGSD\t=",   "\n", "\\\n\t", "", @ldflags_debug )
531
        if ( scalar @ldflags_debug );
532
 
533
    PlatformEntry( "WCE_LDFLAGSP\t=",   "\n", "\\\n\t", "", @ldflags_prod )
534
        if ( scalar @ldflags_prod );
535
 
536
if ( $is_vs2005 )
537
{
538
    $compiler = 'cl';
539
    $linker = 'link';
540
}
541
    PlatformDefine( "
542
WCE_CC		:= $compiler
543
WCE_LINK	:= $linker
544
" );
545
 
546
    Init( $toolchain_info->{'initDef'} );
547
    ToolsetDefines( $toolchain_info->{'def'} );
548
    PlatformDefine ("VSCOMPILER\t= $toolchain_info->{'VSCOMPILER'}" );
549
    ToolsetRules( "vcwce.rul" );
550
    ToolsetRules( "standard.rul" );
551
 
552
#.. define PCLint envrionment
553
    ToolsetRequire( "pclint" );                 # using pclint
554
    PlatformDefine ("LINT_COFILE\t= co-msc60.lnt");
555
    PlatformDefine ("LINT_PRJ_FILE\t=lint.vcembedded");
556
 
557
#.. Cleanup rules
558
#
559
    ToolsetGenerate( "\$(OBJDIR)/$toolchain_info->{'tmp'}.idb" );
560
    ToolsetGenerate( "\$(OBJDIR)/$toolchain_info->{'tmp'}.pch" );
561
    ToolsetGenerate( "\$(OBJDIR)/$toolchain_info->{'tmp'}.pdb" );
562
    ToolsetGenerate( "\$(PDB)" );
563
    ToolsetGenerate( "\$(PDB).tmp" );
564
 
565
 
566
#
567
#   The PDB files need to be compiled up with absolute paths to the source files
568
#   The easiest way to do this is with the makefile rules created with absolute
569
#   paths. Set a global flag to enable this option
570
#
571
    $::UseAbsObjects = 1;
572
 
573
 
574
#.. Extend the CompilerOption directive
575
#   Create a standard data structure
576
#   This is a hash of hashes
577
#       The first hash is keyed by CompileOption keyword
578
#       The second hash contains pairs of values to set or remove
579
#
580
    %::ScmToolsetCompilerOptions =
581
    (
582
        'rtti'               => { 'USE_RTTI', 1 },
583
        'nopdb'              => { 'PDB_NONE', 1 },
584
        'pdb'                => { 'PDB_NONE', undef },
317 dpurdie 585
        'exceptions'         => { 'USE_HANDLING', 1 },
586
        'noexceptions'       => { 'USE_HANDLING', undef },
303 dpurdie 587
    );
588
 
589
    #
590
    #   Set default options
317 dpurdie 591
    #       USE_HANDLING - not always the same default
303 dpurdie 592
    #
317 dpurdie 593
    $::ScmCompilerOpts{'USE_HANDLING'} = $default_ehandling;
303 dpurdie 594
}
595
 
596
##############################################################################
597
#   ToolsetPreprocess()
598
#       Process collected data before the makefile is generated
599
#       This, optional, routine is called from within MakefileGenerate()
600
#       It allows the toolset to massage any of the collected data before
601
#       the makefile is created
602
#
603
##############################################################################
604
sub ToolsetPreprocess
605
{
606
    #
607
    #   Extract the current state of PDB_NONE
608
    #   Are PDB files to be constructed.
609
    #
610
    $pdb_none = $::ScmCompilerOpts{'PDB_NONE'};
611
}
612
 
613
##############################################################################
614
#   ToolsetPostprocess
615
#       Process collected data as the makefile is generated
616
#       This, optional, routine is called from within MakefileGenerate()
617
#       It allows the toolset to massage any of the collected data before
618
#       the makefile is finally closed created
619
#
620
##############################################################################
621
 
622
sub ToolsetPostprocess
623
{
624
    MakeHeader('Toolset Postprocessed Information');
625
 
626
    #
627
    #   Specify the name of the global PDB file. This is used for all
628
    #   compiles other than those associated with building a DLL
629
    #
630
    #   The name of the PDB will be based on either
631
    #       The name of base package
632
    #       The name of the first static library created
633
    #
634
 
635
MakePrint("
636
#
637
#   Export the name of the common PDB file
638
#   All compiler information will be placed in this file
639
#   The name of the file MUST be the same as the name of the output library
640
#
641
PDB		= \$(OBJDIR)/$pdb_file\$(GBE_TYPE).pdb
642
" );
643
 
644
    #
645
    #   Add values to the perl environment
646
    #   May be used by post processing tools to create Visual Studio Projects
647
    #
648
    $::TS_pdb_file = "\$(OBJDIR)/$pdb_file\$(GBE_TYPE).pdb" unless( $pdb_none );
649
    $::TS_sbr_support = 1;
650
 
651
    #
652
    #   Prioritorise target: EXE, DLL, LIB
653
    #
654
    for my $tgt ( $target_file_exe, $target_file_dll, $target_file_lib  )
655
    {
656
        if ( $tgt )
657
        {
658
            $::TS_target_file = $tgt;
659
            last;
660
        }
661
    }
662
}
663
 
664
###############################################################################
665
#   ToolsetCC( $source, $obj, \@args )
666
#       This subroutine takes the user options and builds the rule(s)
667
#       required to compile the source file 'source' to 'obj'
668
#
669
###############################################################################
670
 
671
sub ToolsetCC
672
{
673
    ToolsetCC_common( "CC", @_ );
674
}
675
 
676
sub ToolsetCC_common
677
{
678
    my( $name, $source, $obj, $pArgs ) = @_;
679
    my( $cflags, $pdb );
680
 
681
    foreach $_ ( @$pArgs ) {
682
        if (/--Shared$/) {                      # Building a 'shared' object
683
            $cflags = "$cflags \$(SHCFLAGS)";
684
            $pdb = $::SHOBJ_LIB{$obj}
685
                if (exists $::SHOBJ_LIB{$obj} );
686
 
687
        } else {
343 dpurdie 688
            Message( "$toolset_name $name: unknown option $_ -- ignored\n" );
303 dpurdie 689
        }
690
    }
691
 
692
    MakePrint( "\n\t\$($name)\n" );
693
    MakePadded( 4, "\$(OBJDIR)/$obj.$::o:", "\tCFLAGS +=$cflags\n" )
694
        if ( $cflags );                         # object specific CFLAGS
695
 
696
    if ( $pdb && !$pdb_none )
697
    {
698
        #
699
        #   Determine the name of the PDB file
700
        #   If we are building a shared library then the name of the PDB
701
        #   MUST NOT be the same as the name of the library as there is
702
        #   some stange interaction with the linker ( 50% of the time )
703
        #   This is OK as the file will not be published
704
        #
705
        #   If building a static library then create a PDB of the same
706
        #   name as it may be published directly.
707
        #
708
        my $pdb_file;
709
        if ($cflags )
710
        {
711
            $pdb_file = "\$(OBJDIR)/${pdb}\$(GBE_TYPE)_shlib.pdb";
712
        }
713
        else
714
        {
715
            $pdb_file = "\$(OBJDIR)/${pdb}\$(GBE_TYPE).pdb";
716
        }    
717
 
718
        MakePadded( 4, "\$(OBJDIR)/$obj.$::o:", "\tPDB = $pdb_file\n" );
719
        ToolsetGenerate( $pdb_file );
720
        ToolsetGenerate( $pdb_file . ".tmp" );
721
    }
722
 
723
    #
724
    #   Remove possible Source Browser Files
725
    #
726
    ToolsetGenerate( "\$(OBJDIR)/$obj.sbr" );
727
    MakePrint( "\n" );
728
}
729
 
730
 
731
###############################################################################
732
#   ToolsetCCDepend( $depend, \@sources )
733
#       This subroutine takes the user options and builds the
734
#       rule(s) required to build the dependencies for the source
735
#       files 'sources' to 'depend'.
736
#
737
###############################################################################
738
 
739
sub ToolsetCCDepend
740
{
741
    MakePrint( "\t\$(CCDEPEND)\n" );
742
}
743
 
744
 
745
###############################################################################
746
#   ToolsetCXX( $source, $obj, \@args )
747
#       This subroutine takes the user options and builds the rule(s)
748
#       required to compile the source file 'source' to 'obj'
749
#
750
###############################################################################
751
 
752
sub ToolsetCXX
753
{
754
    ToolsetCC_common( "CXX", @_ );
755
}
756
 
757
###############################################################################
758
#   ToolsetCXXDepend( $depend, \@sources )
759
#       This subroutine takes the user options and builds the
760
#       rule(s) required to build the dependencies for the source
761
#       files 'sources' to 'depend'.
762
#
763
###############################################################################
764
 
765
sub ToolsetCXXDepend
766
{
335 dpurdie 767
    ToolsetCCDepend();
303 dpurdie 768
}
769
 
770
 
771
###############################################################################
772
#   ToolsetAS( $source, $obj, \@args )
773
#       This subroutine takes the user options and builds the rule(s)
774
#       required to compile the source file 'source' to 'obj'
775
#
776
###############################################################################
777
 
778
sub ToolsetAS
779
{
780
    MakePrint( "\n\t\$(AS)\n" );
781
}
782
 
783
sub ToolsetASDepend
784
{
785
}
786
 
787
###############################################################################
788
#   ToolsetAR( $name, \@args, \@objs )
789
#       This subroutine takes the user options and builds the rules
790
#       required to build the library 'name'.
791
#
792
#   Arguments:
793
#       --Def=name              Library definition module
794
#
795
#   Output:
796
#       [ $(LIBDIR)/name$.${a}:   .... ]
797
#           $(AR)
798
#
799
###############################################################################
800
 
801
sub ToolsetAR
802
{
803
    my( $name, $pArgs, $pObjs ) = @_;
804
    my( $def );
805
    my ( $res, @reslist );
806
    my $lib_base = "\$(LIBDIR)/${name}\$(GBE_TYPE)";
807
    my $lib_name = "$lib_base.${a}";
808
 
809
 
810
#.. Parse arguments
811
#
812
    $def = "";                                  # options
813
    $res = "";
814
 
815
    foreach $_ ( @$pArgs ) {
816
        if (/^--Def=(.*)/) {                    # library definition
817
            $def = "$1";
818
 
819
        } elsif (/^--Resource=(.*)/) {          # Resource definition
820
            ($res, @reslist) = ToolsetRClist( "$name", $1 );
821
 
822
        } else {                                # unknown
343 dpurdie 823
            Message( "$toolset_name AR: unknown option $_ -- ignored\n" );
303 dpurdie 824
        }
825
    }
826
 
827
#.. Resource Creation
828
#
829
    MakePrint( "#.. Library Resource ($name)\n\n" );
830
    ToolsetRCrecipe( $res, @reslist )
831
        if ( $res );
832
 
833
#.. Target
834
#
835
    MakePrint( "#.. Library ($name)\n\n" );     # label
836
 
837
    MakePrint( "$lib_name:\tLIBDEF=$def\n" ) if ($def);
838
    MakeEntry( "$lib_name:\t", "", "\\\n\t\t", ".$::o", @$pObjs );
839
    MakePrint( "\\\n\t\t$def" ) if ($def);
840
    MakePrint( "\\\n\t\t$res" ) if ($res);
841
    MakePrint( "\n\t\$(AR)" );
842
 
843
#
844
#   Track the name of the possible target file
845
#   Used when creating Visual Studio projects
846
#
847
    $target_file_lib = $lib_name;
848
 
849
#
850
#   To assist in debugging the static library it is nice to
851
#   keep the PDB file used to build the library, with the library.
852
#
853
#   If the library is being packaged or installed then add the PDB
854
#   file to the package / installation
855
#
856
#   NOTE: Due to the limitations of JATS/MicroSoft only one static
857
#   library can be built with a PDB file. The name of the PDB file
858
#   will be taken from the first static library encountered
859
#
860
    unless ( $pdb_first_lib )
861
    {
862
        $pdb_first_lib = $name;
863
        $pdb_file = $name;
864
    }
865
    else
866
    {
867
        Warning( "Multiple static libraries created with a common PDB file: $pdb_file, $name" )
868
            unless( $pdb_none );
869
    }
870
 
871
    PackageLibAddFiles( $name, "\$(OBJDIR)/$pdb_file\$(GBE_TYPE).pdb", "Class=debug" )
872
        unless( $pdb_none );
873
}
874
 
875
 
876
###############################################################################
877
#   ToolsetARLINT( $name, \@args, \@objs )
878
#       This subroutine takes the user options and builds the rules
879
#       required to build the library 'name'.
880
#
881
#   Arguments:
882
#       --xxx                   No arguments currently defined
883
#
884
#   Output:
885
#       [ $(LIBDIR)/name$_lint:   .... ]
886
#           $(ARLINT)
887
#
888
###############################################################################
889
 
890
sub ToolsetARLINT
891
{
892
    PCLintAR( @_ );
893
}
894
 
895
 
896
###############################################################################
897
#   ToolsetARMerge( $name, \@args, \@libs )
898
#       This subroutine takes the user options and builds the rules
899
#       required to build the library 'name' by merging the specified
900
#       libaries
901
#
902
#   Arguments:
903
#       --xxx                   No arguments currently defined
904
#
905
#   Output:
906
#       [ $(LIBDIR)/name$.${a}:   .... ]
907
#           ...
908
#
909
###############################################################################
910
 
911
sub ToolsetARMerge
912
{
913
    my ($name, $pArgs, $pLibs) = @_;
914
    MakePrint( "\n\t\$(ARMERGE)\n\n" );
915
 
916
    #
917
    #   Package up the PDB's with the library
918
    #   Note: The PDBs will be found in the OBJDIR
919
    #
920
    unless( $pdb_none )
921
    {
922
        for ( @{$pLibs} )
923
        {
924
            s~\$\(LIBDIR\)~\$(OBJDIR)~;
925
            PackageLibAddFiles( $name, "$_\$(GBE_TYPE).pdb", "Class=debug" );
926
        }
927
    }
928
}
929
 
930
 
931
###############################################################################
932
#   ToolsetSHLD $name, \@args, \@objs, \@libraries, $ver )
933
#       This subroutine takes the user options and builds the rules
934
#       required to link a shared library
935
#
936
#   Arguments:
937
#       --Def=xxxx.def[,opts]           # Definition file
938
#           --MutualDll                 # SubOption: Generate a Mutual DLL
939
#       --MutualDll                     # Generate a Mutual DLL (requires --Def=xxx)
940
#       --StubOnly                      # Only generate the stub library (requires --Def=xxx)
941
#       --Resource=xxxx.rc              # Resource file
942
#       --ResourceOnly                  # Only resources in this DLL
943
#       --Implib                        # Alternate ruleset
944
#       --NoPDB                         # Do not package the PDB file
945
#       --NoImplib                      # Do not package the import library
946
#       --Entry=xxxxx                   # Entry point
947
#       --NoAddLibs                     # Do not add libraries
948
#
949
#   Output:
950
#
951
#       There is two supported rule sets differentiated by --Implib
952
#       The two are very similar and generated exportable files of:
953
#
954
#       --Implib
955
#           ${name}.lib         - Stub lib adresses the versioned DLL
956
#           ${name}.${ver}.dll
957
#
958
#       Default
959
#           ${name}.lib         - Stub lib addresses UN-versioned DLL
960
#           ${name}.dll
961
#           ${name}.${ver}.dll
962
#
963
#       Note: Each DLL has an associated PDB file
964
#
965
#       Generation is identical for both rulesets. The default form does
966
#       not export any stub library associated with the versioned DLL.
967
#
968
#   Implementation notes
969
#   The process of creating a DLL and associated import library (LIB) is
970
#
971
#           ${name}.${ver}.dep
972
#           ${name}.${ver}.pdb          - Exported
973
#           ${name}.${ver}.ilk
974
#           ${name}.${ver}.dll          - Exported
975
#           ${name}.${ver}.map
976
#           ${name}.lib                 - Exported + Optional
977
#           ${name}.exp
978
#
979
#       Where:    lib = name
980
#
981
#       #.. Rules ($lib)
982
#
983
#       $(LIBDIR)/${lib}.lib:               $(LIBDIR)/${lib}.${ver}.dll
984
#       $(LIBDIR)/${lib}.pdb:               $(LIBDIR)/${lib}.${ver}.dll
985
#       $(LIBDIR)/${lib}.${ver}.pdb:        $(LIBDIR)/${lib}.${ver}.dll
986
#
987
#       $(LIBDIR)/${lib}.${ver}.dep:        SHBASE=${name}
988
#       $(LIBDIR)/${lib}.${ver}.dep:        SHNAME=${lib}.${ver}
989
#       $(LIBDIR)/${lib}.${ver}.dep:        \$(LIBDIR)
990
#       $(LIBDIR)/${lib}.${ver}.dep:        Makefile
991
#           $(SHLDDEPEND)
992
#
993
#       $(LIBDIR)/${lib}.${ver}.${so}:      SHBASE=${name}
994
#       $(LIBDIR)/${lib}.${ver}.${so}:      SHNAME=${lib}.${ver}
995
#       $(LIBDIR)/${lib}.${ver}.${so}:      CFLAGS+=$(SHCFLAGS)
996
#       $(LIBDIR)/${lib}.${ver}.${so}:      CXXLAGS+=$(SHCXXFLAGS)
997
#       $(LIBDIR)/${lib}.${ver}.${so}:      ${def}
998
#       $(LIBDIR)/${lib}.${ver}.${so}:      $(OBJDIR)/${name} \
999
#                       object list ... \
1000
#                       $(LIBDIR)/${lib}.${ver}.dep
1001
#           $(SHLD)
1002
#           @$(cp) -f $(LIBDIR)/${lib}.${ver}.pdb $(LIBDIR)/${lib}.pdb
1003
#
1004
#       ifneq "$(findstring $(IFLAG),23)" ""
1005
#       -include        "$(LIBDIR)/${lib}.${ver}.dep"
1006
#       endif
1007
#
1008
#       #.. Linker commands ($lib)
1009
#
1010
#       ${lib}_ld       += ...
1011
#               standard flags                          \
1012
#               -implib:$${lib}.lib
1013
#
1014
#       #.. Linker commands ($lib)
1015
#
1016
#       ${lib}_shdp     += ...
1017
#
1018
###############################################################################
1019
 
1020
sub ToolsetSHLD
1021
{
1022
    our( $name, $pArgs, $pObjs, $pLibs, $ver ) = @_;
1023
    our( $def, $mutual_dll, $res, @reslist, $doimplib, $stub_only );
1024
    our( $no_implib, $no_pdb, $resource_only );
1025
    our( $entry, $noaddlibs );
1026
 
1027
#.. Parse arguments
1028
#
1029
    $def = "";                                  # options
1030
    $doimplib = 0;
1031
    $res = "";
1032
    $no_pdb = $pdb_none;
1033
 
1034
    foreach $_ ( @$pArgs ) {
1035
        if (/^--Def=(.*?)(\,(.*))?$/) {         # Library definition
1036
            #
1037
            #   Locate the Def file.
1038
            #   If it is a generate file so it will be in the SRCS hash
1039
            #   Otherwise the user will have to use Src to locate the file
1040
            #
1041
            $def = MakeSrcResolve($1);
1042
 
1043
            #
1044
            #   Process sub options to --Def
1045
            #
1046
            next unless ($2);
1047
            if ( $3 =~ /^--MutualDll$/ ) {
1048
                $mutual_dll = 1;
1049
            } else {
343 dpurdie 1050
                Message( "$toolset_name SHLD: unknown option $_ -- ignored\n" );
303 dpurdie 1051
            }
1052
 
1053
        } elsif (/^--Resource=(.*)/) {          # Resource definition
1054
            ($res, @reslist) = ToolsetRClist( "$name/$name", $1 );
1055
 
1056
        } elsif (/^--ResourceOnly/) {          # Resource definition
1057
            $resource_only = 1;
1058
 
1059
        } elsif (/^--Implib$/) {
1060
            $doimplib = 1;
1061
 
1062
        } elsif (/^--NoImplib$/) {
1063
            $no_implib = 1;
1064
 
1065
        } elsif (/^--NoPDB$/) {
1066
            $no_pdb = 1;
1067
 
1068
        } elsif (/^--Entry=(.*)/) {
1069
            $entry = $1;
1070
 
1071
        } elsif (/^--NoAddLib/) {
1072
            $noaddlibs = 1;
1073
 
1074
        } elsif (/^--MutualDll$/) {
1075
            $mutual_dll = 1;
1076
 
1077
        } elsif (/^--Stubonly/) {
1078
            $stub_only = 1;
1079
 
1080
        } else {                                # unknown
343 dpurdie 1081
            Message( "$toolset_name SHLD: unknown option $_ -- ignored\n" );
303 dpurdie 1082
        }
1083
    }
1084
 
1085
    #
1086
    #   Sanity test
1087
    #
343 dpurdie 1088
    Error ("$toolset_name SHLD:Stubonly option requires --Def=file ")
303 dpurdie 1089
        if ( $stub_only && ! $def );
1090
 
343 dpurdie 1091
    Error ("$toolset_name SHLD:MutualDll option requires --Def=file ")
303 dpurdie 1092
        if ( $mutual_dll && ! $def );
1093
 
1094
 
1095
 
1096
#.. Build rules
1097
#
1098
#   base    -   Basic name of the DLL
1099
#   name    -   Name of the Export library (Optional)
1100
#   lib     -   Name of the DLL
1101
#
1102
    sub BuildSHLD
1103
    {
1104
        my ($base, $name, $lib) = @_;
1105
        my $full = $lib.".$::so";
1106
        my $link_with_def;
1107
 
1108
    #.. Cleanup rules
1109
    #
1110
    #   ld      Linker command file
1111
    #   map     Map file
1112
    #   pdb     Microsoft C/C++ program database
1113
    #   ilk     Microsoft Linker Database
1114
    #
1115
        ToolsetGenerate( "\$(LIBDIR)/${lib}.ld" );
1116
        ToolsetGenerate( "\$(LIBDIR)/${lib}.map" );
1117
        ToolsetGenerate( "\$(LIBDIR)/${lib}.exp" );
1118
        ToolsetGenerate( "\$(LIBDIR)/${lib}.ilk" );
1119
        ToolsetGenerate( "\$(LIBDIR)/${full}" );
1120
 
1121
    #.. Linker rules
1122
    #
1123
        my ($io) = ToolsetPrinter::New();
1124
 
1125
        my $import_lib;
1126
        my $export_file;
1127
 
1128
        if ( $name && $def && ($mutual_dll || $stub_only ) )
1129
        {
1130
            #
1131
            #   Creating an Export library from user .DEF file
1132
            #   It is possible to create the stub library in the LIB phase
1133
            #   which allows DLLs with mutual imports
1134
            #
1135
            $io->Label( "Import(stub) library for mutual exports", $name );
1136
            $export_file = "\$(LIBDIR)/${name}.exp";
1137
 
1138
            #
1139
            #   Rules and recipe to generate the stub library
1140
            #
1141
            $io->Prt( "\$(LIBDIR)/${name}.exp:\t\$(LIBDIR)/${name}.${a}\n" );
1142
            $io->Prt( "\$(LIBDIR)/${name}.${a}:\tLIBDEF=$def\n" );
1143
            $io->Prt( "\$(LIBDIR)/${name}.${a}:\tLIBNAME=$lib\n" );
1144
            $io->Entry( "\$(LIBDIR)/${name}.${a}: \\\n\t\t\$(OBJDIR)/${base}",
1145
                                            "", " \\\n\t\t", ".$::o", @$pObjs );
1146
            $io->Prt( " \\\n\t\t$def" );
1147
            $io->Prt( "\n\t\t\$(AR)\n" );
1148
            $io->Newline();
1149
 
1150
            #
1151
            #   Files to be cleanup up
1152
            #
1153
            ToolsetGenerate( "\$(LIBDIR)/${name}.exp" );
1154
            ToolsetGenerate( "\$(LIBDIR)/${name}.${a}" );
1155
 
1156
            #
1157
            #   If the DLL is being packaged/installed then add the static
1158
            #   stub library to the packaging lists as a static library
1159
            #   This will allow the stub library to be installed with the
1160
            #   static libraries and thus allow DLL's with mutual imports
1161
            #
1162
            PackageShlibAddLibFiles ($base, "\$(LIBDIR)/${name}.${a}" )
1163
                unless ($resource_only);
1164
 
1165
            #
1166
            #   Add the stub library to the list of libraries being created
1167
            #   Note: Don't do if not created with .DEF file
1168
            #
1169
            push @::LIBS, $base;
1170
 
1171
        }
1172
        else
1173
        {
1174
            #
1175
            #   The stub library is created as part of the DLL generation
1176
            #   Whether we like it or not - so we need to control the name
1177
            #   and location
1178
            #
1179
            my $slname = ($name) ? $name : $lib;
1180
            $import_lib = "\$(LIBDIR)/${slname}.${a}";
1181
 
1182
            $io->Label( "Import(stub) library", $slname );
1183
            $io->Prt( "$import_lib:\t\$(LIBDIR)/${full}\n" );
1184
            $io->Newline();
1185
 
1186
            ToolsetGenerate( $import_lib );
1187
            ToolsetGenerate( "\$(LIBDIR)/${slname}.exp" );
1188
 
1189
            #
1190
            #   Package the generated stub library, if it is being
1191
            #   created on request.
1192
            #
1193
            #   Package it with the shared libaries and not the static
1194
            #   libraries as it will be created with the shared library
1195
            #
1196
            PackageShlibAddFiles ($base, $import_lib, 'Class=lib' )
1197
                if ($name && ! $no_implib && ! $resource_only);
1198
 
1199
            #
1200
            #   Indicate that we will be linking with a DEF file
1201
            #
1202
            $link_with_def = 1 if ( $def );
1203
        }
1204
 
1205
        #
1206
        #   If we are only creating a stub library, then the hard work has been
1207
        #   done.
1208
        #
1209
        return
1210
            if ($stub_only);
1211
 
1212
        $io->Label( "Shared library", $name );
1213
 
1214
        #
1215
        #   The process of creating a DLL will generate PDB file
1216
        #   Control the name of the PDB file
1217
        #
1218
        my $pdb_file = "\$(LIBDIR)/${lib}.pdb";
1219
        unless( $no_pdb )
1220
        {
1221
            $io->Prt( "$pdb_file:\t\$(LIBDIR)/${full}\n" );
1222
            ToolsetGenerate( $pdb_file );
1223
        }
1224
 
1225
        #
1226
        #   Package the PDB file up with the DLL
1227
        #   Package the DLL - now that we know its proper name
1228
        #
1229
        PackageShlibAddFiles( $base, $pdb_file, 'Class=debug' ) unless $no_pdb ;
1230
        PackageShlibAddFiles( $base, "\$(LIBDIR)/${full}" );
1231
 
1232
        #
1233
        #   Generate Shared Library dependency information
1234
        #
335 dpurdie 1235
        my $dep = $io->SetShldTarget( $lib );
303 dpurdie 1236
 
1237
        #
1238
        #   Generate rules and recipes to create the body of the shared
1239
        #   library. Several build variables are overiden when creating
1240
        #   a shared library.
1241
        #
1242
        $io->Prt( "\$(LIBDIR)/${full}:\tSHBASE=${lib}\n" );
1243
        $io->Prt( "\$(LIBDIR)/${full}:\tSHNAME=${lib}\n" );
1244
        $io->Prt( "\$(LIBDIR)/${full}:\tCFLAGS+=\$(SHCFLAGS)\n" );
1245
        $io->Prt( "\$(LIBDIR)/${full}:\tCXXLAGS+=\$(SHCXXFLAGS)\n" );
1246
        $io->Prt( "\$(LIBDIR)/${full}:\t$export_file\n" ) if ($export_file );
1247
        $io->Prt( "\$(LIBDIR)/${full}:\t$res\n" ) if ( $res );
1248
 
335 dpurdie 1249
        $io->Entry( "\$(LIBDIR)/${full}: $dep \\\n\t\t\$(OBJDIR)/${base}",
303 dpurdie 1250
            "", " \\\n\t\t", ".$::o", @$pObjs );
1251
 
1252
        $io->Prt( " \\\n\t\t$def" ) if ( $link_with_def );
335 dpurdie 1253
        $io->Prt( "\n\t\$(SHLD)\n" );
303 dpurdie 1254
 
1255
        $io->Newline();
1256
 
1257
        #.. Linker command file
1258
        #
1259
        #       Now the fun part... piecing together a variable ${name}_shld
1260
        #       which ends up in the command file.
1261
        #
1262
        $io->SetTag( "${lib}_shld" );          # command tag
1263
 
1264
        $io->Label( "Linker commands", $name ); # label
1265
 
1266
        $io->Cmd( "-dll" );
1267
        $io->Cmd( "-noentry" )if ($resource_only);
1268
        $io->Cmd( "-def:$def" ) if ($link_with_def);
1269
        $io->Cmd( "-out:\$(subst /,\\\\,\$(LIBDIR)/${full})" );
1270
        $io->Cmd( "-implib:\$(subst /,\\\\,$import_lib)" ) if ($import_lib);
1271
        $io->Cmd( "-pdb:\$(subst /,\\\\,$pdb_file)" ) unless ( $no_pdb );
1272
        $io->Cmd( "-debug:none" )                     if ($no_pdb);
1273
        $io->Cmd( "-pdb:none" )                       if ($no_pdb);
1274
        $io->Cmd( "-entry:$entry" )                   if ($entry);
1275
        $io->Cmd( "-map:\$(subst /,\\\\,\$(LIBDIR)/${lib}).map" );
1276
        $io->Cmd( "\$(subst /,\\\\,$res)" ) if ( $res );
1277
        $io->Cmd( "\$(subst /,\\\\,$export_file)" ) if ( $export_file );
1278
 
1279
                                                # object list
1280
        $io->ObjList( $name, $pObjs, \&ToolsetObjRecipe );
1281
 
1282
                                                # library list
1283
        $io->LibList( $name, $pLibs, \&ToolsetLibRecipe );
1284
 
1285
        $io->Newline();
1286
 
1287
        #.. Dependency link,
335 dpurdie 1288
        #   Create a library dependency file
1289
        #       Create command file to build applicaton dependency list
1290
        #       from the list of dependent libraries
303 dpurdie 1291
        #
335 dpurdie 1292
        #       Create makefile directives to include the dependency
1293
        #       list into the makefile.
303 dpurdie 1294
        #
335 dpurdie 1295
        $io->DepRules( $pLibs, \&ToolsetLibRecipe, "\$(LIBDIR)/${full}" );
1296
        $io->SHLDDEPEND( $name, $lib );
303 dpurdie 1297
    }
1298
 
1299
    ToolsetLibStd( $pLibs )                    # push standard libraries
1300
        unless ( $noaddlibs );
1301
 
1302
    if ( $doimplib ) {
1303
        #
1304
        #   --Implib flavor will create
1305
        #       a) Import library   $name$(GBE_TYPE).lib
1306
        #       b) Versioned DLL    $name$(GBE_TYPE).xx.xx.xx.dll
1307
        #
1308
        $target_file_dll = "\$(LIBDIR)/$name\$(GBE_TYPE).$ver.$::so";
1309
        BuildSHLD(
1310
            "$name",                        # Base Name
1311
            "$name\$(GBE_TYPE)",            # Name of Export Lib
1312
            "$name\$(GBE_TYPE).$ver");      # Name of the DLL + PDB
1313
 
1314
    } else {
1315
        #
1316
        #   Original flavor will create
1317
        #       a) Import library   $name$(GBE_TYPE).lib    ---+
1318
        #       b) Unversioned DLL  $name$(GBE_TYPE).dll    <--+
1319
        #       c) Versioned DLL    $name$(GBE_TYPE).xx.xx.xx.dll
1320
        #
1321
        MakePrint(
1322
            "# .. Versioned image\n\n".
1323
            "\$(LIBDIR)/${name}\$(GBE_TYPE).$::so:\t".
1324
            "\$(LIBDIR)/${name}\$(GBE_TYPE).$ver.$::so\n".
1325
            "\n" );
1326
 
1327
        $target_file_dll = "\$(LIBDIR)/$name\$(GBE_TYPE).$::so";
1328
        BuildSHLD( "$name", "$name\$(GBE_TYPE)" , "$name\$(GBE_TYPE)" );
1329
        BuildSHLD( "$name", ""                  , "$name\$(GBE_TYPE).$ver" );
1330
    }
1331
 
1332
    #.. Resource File
1333
    #
1334
    ToolsetRCrecipe( $res, @reslist )
1335
        if ( $res );
1336
}
1337
 
1338
 
1339
###############################################################################
1340
#   ToolsetSHLDLINT $name, \@args, \@objs, \@libraries )
1341
#       This subroutine takes the user options and builds the rules
1342
#       required to lint the program 'name'.
1343
#
1344
#   Arguments:
1345
#       (none)
1346
#
1347
#   Output:
1348
#       [ $(LIBDIR)/$name_lint:   .... ]
1349
#           $(SHLIBLINT)
1350
#
1351
###############################################################################
1352
 
1353
sub ToolsetSHLDLINT
1354
{
1355
    PCLintSHLIB( @_ );
1356
}
1357
 
1358
 
1359
###############################################################################
335 dpurdie 1360
# Function        : ToolsetLD
303 dpurdie 1361
#
335 dpurdie 1362
# Description     : Takes the user options and builds the rules required to
1363
#                   link the program 'name'.
303 dpurdie 1364
#
335 dpurdie 1365
# Inputs          : $name           - base name of the program
1366
#                   $pArgs          - Ref to program arguments
1367
#                   $pObjs          - Ref to program objects
1368
#                   $pLibs          - Ref to program library list
303 dpurdie 1369
#
335 dpurdie 1370
# Returns         : Nothing
303 dpurdie 1371
#
335 dpurdie 1372
# Output:         : Rules and recipes to create a program
1373
#                       Create program rules and recipes
1374
#                       Create linker input script
1375
#                       Create library dependency list
1376
#                       Include library dependency information
303 dpurdie 1377
#
1378
sub ToolsetLD
1379
{
1380
    my ( $name, $pArgs, $pObjs, $pLibs ) = @_;
1381
    my ( $res, @reslist );
1382
    my $no_pdb =$pdb_none;
1383
    our( $entry, $noaddlibs );
1384
 
1385
#.. Parse arguments
1386
#
1387
    foreach ( @$pArgs ) {
1388
        if (/^--Resource=(.*)/) {               # Resource definition
1389
            ($res, @reslist) = ToolsetRClist( $name, $1 );
1390
 
1391
        } elsif (/^--NoPDB$/) {
1392
            $no_pdb = 1;
1393
 
1394
        } elsif (/^--Entry=(.*)/) {
1395
            $entry = $1;
1396
 
1397
        } elsif (/^--NoAddLib/) {
1398
            $noaddlibs = 1;
1399
 
1400
        } else {
343 dpurdie 1401
            Message( "$toolset_name LD: unknown option $_ -- ignored\n" );
303 dpurdie 1402
 
1403
        }
1404
    }
1405
 
335 dpurdie 1406
#.. Names of important files
1407
#
1408
    my $base = "\$(BINDIR)/${name}";
1409
    my $full = $base . $::exe;
1410
    my $map  = $base . '.map';
1411
    my $pdb  = $base . '.pdb';
1412
 
1413
 
303 dpurdie 1414
#.. Cleanup rules
1415
#
1416
#   ld      Linker command file
1417
#   map     Map file
1418
#   pdb     Microsoft C/C++ program database
1419
#   ilk     Microsoft Linker Database
1420
#   res     Compiled resource script
1421
#
335 dpurdie 1422
    ToolsetGenerate( $map );
1423
    ToolsetGenerate( $pdb );
1424
    ToolsetGenerate( $base . '.ld' );
1425
    ToolsetGenerate( $base . '.ilk' );
303 dpurdie 1426
 
335 dpurdie 1427
#.. Toolset Printer
303 dpurdie 1428
#
1429
    my ($io) = ToolsetPrinter::New();
335 dpurdie 1430
    my $dep = $io->SetLdTarget( $name );
303 dpurdie 1431
 
335 dpurdie 1432
#
1433
#.. Linker command
1434
#
1435
    $io->Prt( "$full : $dep " );
1436
    $io->Entry( "", "", "\\\n\t", ".$::o ", @$pObjs );
1437
    $io->Prt( "\\\n\t$res " ) if ( $res );
1438
    $io->Prt( "\n\t\$(LD)\n\n" );
303 dpurdie 1439
 
1440
#.. Linker command file
1441
#
1442
#       Now piece together a variable $(name_ld) which ends up in
1443
#       the command file linking the application.
1444
#
1445
    $io->SetTag( "${name}_ld" );                # macro tag
1446
 
1447
    $io->Label( "Linker commands", $name );     # label
1448
 
335 dpurdie 1449
    $io->Cmd( "-out:\$(subst /,\\\\,$full)" );
1450
    $io->Cmd( "-pdb:\$(subst /,\\\\,$pdb)" )        unless ($no_pdb);
303 dpurdie 1451
    $io->Cmd( "-debug:none" )                                  if ($no_pdb);
1452
    $io->Cmd( "-pdb:none" )                                    if ($no_pdb);
1453
    $io->Cmd( "-entry:$entry" )                                if ($entry);
335 dpurdie 1454
    $io->Cmd( "-map:\$(subst /,\\\\,$map)" );
1455
    $io->Cmd( "\$(subst /,\\\\,$res)" )             if ( $res );
303 dpurdie 1456
 
335 dpurdie 1457
    ToolsetLibStd( $pLibs ) unless ( $noaddlibs );      # push standard libraries
1458
    $io->ObjList( $name, $pObjs, \&ToolsetObjRecipe );  # object list
1459
    $io->LibList( $name, $pLibs, \&ToolsetLibRecipe );  # library list
303 dpurdie 1460
    $io->Newline();
1461
 
335 dpurdie 1462
    #.. Dependency link,
1463
    #   Create a library dependency file
1464
    #       Create command file to build applicaton dependency list
1465
    #       from the list of dependent libraries
1466
    #
1467
    #       Create makefile directives to include the dependency
1468
    #       list into the makefile.
1469
    #
1470
    $io->DepRules( $pLibs, \&ToolsetLibRecipe, $full );
1471
    $io->LDDEPEND();
303 dpurdie 1472
 
1473
#.. Compile up the resource file
1474
#
1475
    ToolsetRCrecipe( $res, @reslist )
1476
        if ( $res );
1477
 
1478
#.. Package up the PDB file with the program
1479
#
335 dpurdie 1480
    PackageProgAddFiles ( $name, $full );
1481
    PackageProgAddFiles ( $name, $pdb, "Class=debug" ) unless ( $no_pdb );
303 dpurdie 1482
 
1483
#
1484
#   Track the name of the possible target file
1485
#   Used when creating Visual Studio projects
1486
#
335 dpurdie 1487
    $target_file_exe = $full;
303 dpurdie 1488
}
1489
 
1490
 
1491
###############################################################################
1492
#   ToolsetLD( $name, \@args, \@objs, \@libraries, \@csrc, \@cxxsrc )
1493
#       This subroutine takes the user options and builds the rules
1494
#       required to lint the program 'name'.
1495
#
1496
#   Arguments:
1497
#       (none)
1498
#
1499
#   Output:
1500
#       [ $(BINDIR)/$name_lint:   .... ]
1501
#           $(LDLINT)
1502
#
1503
###############################################################################
1504
 
1505
sub ToolsetLDLINT
1506
{
1507
    PCLintLD( @_ );
1508
}
1509
 
1510
 
1511
########################################################################
1512
#
1513
#   Push standard "system" libraries. This is a helper function
1514
#   used within this toolset.
1515
#
1516
#   Arguments:
1517
#       $plib       Reference to library array.
1518
#
1519
########################################################################
1520
 
1521
sub ToolsetLibStd
1522
{
1523
    my ($plib) = @_;
1524
 
1525
    #
1526
    #   Only add libraries if required
1527
    #
1528
    return unless( $::ScmCompilerOpts{'ADDLINKLIBS'} );
1529
 
1530
}
1531
 
1532
 
1533
########################################################################
1534
#
1535
#   Generate a linker object recipe.  This is a helper function used 
1536
#   within this toolset.
1537
#
1538
#   Arguments:
1539
#       $io         I/O stream
1540
#
1541
#       $target     Name of the target
1542
#
1543
#       $obj        Library specification
1544
#
1545
########################################################################
1546
 
1547
sub ToolsetObjRecipe
1548
{
1549
    my ($io, $target, $obj) = @_;
1550
 
1551
    $io->Cmd( "\$(subst /,\\\\,\$(strip $obj)).$::o" );
1552
}
1553
 
1554
 
1555
########################################################################
1556
#
1557
#   Generate a linker/depend library recipe.  This is a helper function
1558
#   used within this toolset.
1559
#
1560
#   Arguments:
1561
#       $io         I/O stream
1562
#
1563
#       $target     Name of the target
1564
#
1565
#       $lib        Library specification
1566
#
1567
#       $dp         If building a depend list, the full target name.
1568
#
1569
########################################################################
1570
 
1571
sub ToolsetLibRecipe
1572
{
1573
    my ($io, $target, $lib, $dp) = @_;
1574
 
1575
    return                                      # ignore (compat)
1576
        if ( $lib eq "rt" ||        $lib eq "thread" ||
1577
             $lib eq "pthread" ||   $lib eq "nsl" ||
1578
             $lib eq "socket" );
1579
 
1580
    if ( !defined($dp) ) {                      # linker
1581
        $io->Cmd( "\$(subst /,\\\\,\$(strip $lib)).$::a" );
1582
 
1583
    } else {                                    # depend
1584
        $io->Cmd( "$dp:\t@(vlib2,$lib,LIB)" );
1585
    }
1586
}
1587
 
1588
 
1589
########################################################################
1590
#
1591
#   Parse resource file data
1592
#   This is a helper function used within this toolset
1593
#
1594
#   Arguments   : $1  BaseName
1595
#                 $2  The users resource list
1596
#                     This is a list of comma seperated files
1597
#                     The first file is the main resource script
1598
#
1599
#   Returns     : An array of resource files with full pathnames
1600
#                 [0] = The output file
1601
#                 [1] = The input file
1602
#                 [..] = Other input files
1603
#
1604
########################################################################
1605
 
1606
sub ToolsetRClist
1607
{
1608
    my ($name, $files) = @_;
1609
    my @result;
1610
 
1611
    #
1612
    #   Generate the name of the output file
1613
    #
1614
    push @result, "\$(OBJDIR)/$name.res";
1615
 
1616
    #
1617
    #   Process each user file
1618
    #
335 dpurdie 1619
    for (split( '\s*,\s*', $files ))
303 dpurdie 1620
    {
1621
        #
1622
        #   Locate the file.
1623
        #   If it is a generate file so it will be in the SRCS hash
1624
        #   Other wise the use will have to use Src to locate the file
1625
        #
1626
        push @result, MakeSrcResolve($_);
1627
    }
1628
 
1629
    #
1630
    #   Return the array to the user
1631
    #
1632
    return @result;
1633
}
1634
 
1635
 
1636
########################################################################
1637
#
1638
#   Generate a resource file recipe
1639
#   This is a helper function used within this tool
1640
#
1641
#   Arguments   : $1  Output resource file
1642
#                 ..  Input resource files
1643
#
1644
########################################################################
1645
 
1646
sub ToolsetRCrecipe
1647
{
1648
    my ($out, @in) = @_;
1649
 
1650
    #
1651
    #   Cleanup
1652
    #
1653
    ToolsetGenerate( $out );
1654
 
1655
    #
1656
    #   Recipe
1657
    #
1658
    MakePrint( "\n#.. Compile Resource file: $out\n\n" );
1659
    MakePrint( "$out:\t\$(GBE_PLATFORM).mk\n" );
1660
    MakeEntry( "$out:\t", "", "\\\n\t\t", " ", @in );
1661
    MakePrint( "\n\t\$(RC)\n" );
1662
    MakePrint( "\n" );
1663
}
1664
 
1665
########################################################################
1666
#
1667
#   Generate a project from the provided project file
1668
#
1669
#   Arguments   : $name             - Base name of the project
1670
#                 $project          - Path to the project file
1671
#                 $pArgs            - Project specific options
1672
#
1673
########################################################################
1674
 
1675
my $project_defines_done = 0;
1676
sub ToolsetPROJECT
1677
{
1678
    my( $name, $project, $pArgs ) = @_;
1679
    my $buildcmd = $toolchain_info->{'buildcmd'};
1680
    my $cleancmd = $toolchain_info->{'cleancmd'};
343 dpurdie 1681
    my $release = ${$toolchain_info->{'def_targets'}}[0] || 'RELEASE';
1682
    my $debug =   ${$toolchain_info->{'def_targets'}}[1] || 'DEBUG';
303 dpurdie 1683
 
1684
    #
1685
    #   Process options
1686
    #
1687
    foreach ( @$pArgs ) {
343 dpurdie 1688
        if ( m/^--TargetProd*=(.+)/ ) {
1689
            $release = $1;
1690
 
1691
        } elsif ( m/^--TargetDebug=(.+)/ ) {
1692
            $debug = $1;
1693
 
1694
        } else {
1695
            Message( "$toolset_name PROJECT: unknown option $_ -- ignored\n" );
1696
        }
303 dpurdie 1697
    }
343 dpurdie 1698
 
303 dpurdie 1699
    my ($io) = ToolsetPrinter::New();
1700
 
1701
    #
343 dpurdie 1702
    #   Setup toolset specific difinitions. Once
303 dpurdie 1703
    #
1704
    unless( $project_defines_done )
1705
    {
1706
        $project_defines_done = 1;
343 dpurdie 1707
        $io->PrtLn( 'project_target = $(if $(findstring 1,$(DEBUG)),$2,$1)' );
303 dpurdie 1708
        $io->Newline();
1709
    }
1710
 
1711
    #
1712
    #   Process the build and clean commands
1713
    #       Substitute arguments
1714
    #           =TYPE=
1715
    #           =LOG=
1716
    #           =DSW=
1717
    #           =CEPLATFORM=
1718
    #
343 dpurdie 1719
    $buildcmd =~ s~=TYPE=~"\$(call project_target,$release,$debug)"~g;
303 dpurdie 1720
    $buildcmd =~ s~=LOG=~$name\$(GBE_TYPE).log~g;
1721
    $buildcmd =~ s~=DSW=~$project~g;
1722
    $buildcmd =~ s~=CEPLATFORM=~\$(WCE_PLATFORM)~g;
1723
 
343 dpurdie 1724
    $cleancmd =~ s~=TYPE=~"\$(call project_target,$release,$debug)"~g;
303 dpurdie 1725
    $cleancmd =~ s~=LOG=~$name\$(GBE_TYPE).log~g;
1726
    $cleancmd =~ s~=DSW=~$project~g;
1727
    $cleancmd =~ s~=CEPLATFORM=~\$(WCE_PLATFORM)~g;
1728
 
1729
    #
1730
    #   Generate the recipe to create the project
1731
    #
1732
    $io->Label( "Build project", $name );
1733
    $io->PrtLn( "Project_$name: $project" );
1734
    $io->PrtLn( "\t\$(XX_PRE)( \$(rm) -f $name\$(GBE_TYPE).log; \\" );
1735
    $io->PrtLn( "\t\$(show_environment); \\" );
1736
    $io->PrtLn( "\t$buildcmd; \\" );
1737
    $io->PrtLn( "\tret=\$\$?; \\" );
1738
    $io->PrtLn( "\t\$(GBE_BIN)/cat $name\$(GBE_TYPE).log; \\" );
1739
    $io->PrtLn( "\texit \$\$ret )" );
1740
    $io->Newline();
1741
 
1742
    #
1743
    #   Generate the recipe to clean the project
1744
    #
1745
    $io->Label( "Clean project", $name );
1746
    $io->PrtLn( "ProjectClean_$name: $project" );
1747
    $io->PrtLn( "\t-\$(XX_PRE)$cleancmd" );
1748
    $io->PrtLn( "\t-\$(XX_PRE)\$(rm) -f $name\$(GBE_TYPE).log" );
1749
    $io->Newline();
1750
 
1751
}
1752
 
1753
 
1754
#.. Successful termination
1755
1;
1756