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