Subversion Repositories DevTools

Rev

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