Subversion Repositories DevTools

Rev

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

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