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