Subversion Repositories DevTools

Rev

Rev 307 | Go to most recent revision | Details | Last modification | View Log | RSS feed

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