Subversion Repositories DevTools

Rev

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

Rev Author Line No. Line
303 dpurdie 1
# -*- mode: perl; indent-width: 4; show-tabs: yes; -*-
2
#
3
# Module name   : vcwce
4
# Module type   : Makefile system
5
# Compiler(s)   : ANSI C
6
# Environment(s): WCE
7
#
8
# Description:
9
#   Visual C/C++ for WCE
10
#
11
#............................................................................#
12
 
13
use strict;
14
use warnings;
15
 
16
#
17
#   Global data
18
#
19
my $pdb_file = "\$(GBE_PBASE)";
20
my $pdb_first_lib;
21
my $target_file_lib;
22
my $target_file_dll;
23
my $target_file_exe;
24
my $pdb_none;
25
 
26
##############################################################################
27
#   Toolchain information
28
#   Abstarct out minor toolchain differences into a data structure
29
#
30
my $toolchain_info;
31
my %ToolChainData =
32
    (
33
        'EVC4'      =>  {  'def'        => 'vcwce.def' ,
34
                           'initDef'    => 'vcembedded',
35
                           'wceroot'    => 'Microsoft eMbedded C++ 4.0',
36
                           'buildcmd'   => 'evc =DSW= /make "ALL - =TYPE=" /use_env /CEConfig="=CEPLATFORM=" /out =LOG=',
37
                           'cleancmd'   => 'evc =DSW= /make "ALL - =TYPE=" /clean /use_env /CEConfig="=CEPLATFORM="',
38
                           'tmp'        => 'vc60',
39
                           'VSCOMPILER' => '1',
40
                           },
41
 
42
 
43
        'VS2005'    =>  {  'def'        => 'vcembedded2005.def' ,
44
                           'initDef'    => 'vcembedded',
45
                           'buildcmd'   => 'devenv =DSW= /build =TYPE= /useenv /out =LOG=' ,
46
                           'cleancmd'   => 'devenv =DSW= /clean =TYPE= /useenv' ,
47
                           'tmp'        => 'vc80',
48
                           'VSCOMPILER' => '2',
49
 
50
                           'wceroot'    => 'Microsoft Visual Studio 8/VC/ce',
51
                           'includes'   => [    '$(WCEROOT)/include',
52
                                                '$(WCEROOT)/atlmfc/include',
53
                                           ],
54
                           'libs'       => [    '$(WCEROOT)/lib/$(WCE_TARGETCPU)',
55
                                                '$(WCEROOT)/atlmfc/lib/$(WCE_TARGETCPU)',
56
                                           ],
57
                           },
58
 
59
    );
60
 
61
 
62
##############################################################################
63
#   ToolsetInit()
64
#       Runtime initialisation
65
#
66
##############################################################################
67
 
68
my( $WCEVersion )               = "";
69
my( $WCESubsystem )             = "";
70
my( $WCEPlatform )              = "";
71
my( $WCEPlatformDefine )        = "";
72
my( $WCEPlatformClean )         = "";
73
my( $WCETargetCPU )             = "";
74
my( $WCEHostCPU )               = "";
75
my( $WCEToolchain )             = "";
76
 
77
ToolsetInit();
78
 
79
sub ToolsetInit
80
{
81
    my( $wceroot, $sdkroot );
82
    my( $compiler, $linker, $vstool );
83
    my( @defines ) = ();
84
    my( @cflags, @cflags_debug, @cflags_prod ) = ();
85
    my( @libflags, @ldflags, @ldflags_debug, @ldflags_prod ) = ();
86
    my $is_vs2005;
317 dpurdie 87
    my $default_ehandling = undef;
303 dpurdie 88
 
89
#.. Standard.rul requirements
90
#
91
    $::s = "asm";
92
    $::o = "obj";
93
    $::a = "lib";
94
    $::so = "dll";
95
    $::exe = ".exe";
96
 
97
#.. Toolset configuration
98
#
99
    $::ScmToolsetVersion = "1.0.0";             # our version
100
    $::ScmToolsetGenerate = 0;                  # generate optional
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
{
746
    MakePrint( "\t\$(CCDEPEND)\n" );
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
    #   dep     Dependency file
1090
    #   ld      Linker command file
1091
    #   map     Map file
1092
    #   pdb     Microsoft C/C++ program database
1093
    #   ilk     Microsoft Linker Database
1094
    #
1095
        ToolsetGenerate( "\$(LIBDIR)/${lib}.ld" );
1096
        ToolsetGenerate( "\$(LIBDIR)/${lib}.dep" );
1097
        ToolsetGenerate( "\$(LIBDIR)/${lib}.map" );
1098
        ToolsetGenerate( "\$(LIBDIR)/${lib}.exp" );
1099
        ToolsetGenerate( "\$(LIBDIR)/${lib}.ilk" );
1100
        ToolsetGenerate( "\$(LIBDIR)/${full}" );
1101
 
1102
    #.. Linker rules
1103
    #
1104
        my ($io) = ToolsetPrinter::New();
1105
 
1106
        my $import_lib;
1107
        my $export_file;
1108
 
1109
        if ( $name && $def && ($mutual_dll || $stub_only ) )
1110
        {
1111
            #
1112
            #   Creating an Export library from user .DEF file
1113
            #   It is possible to create the stub library in the LIB phase
1114
            #   which allows DLLs with mutual imports
1115
            #
1116
            $io->Label( "Import(stub) library for mutual exports", $name );
1117
            $export_file = "\$(LIBDIR)/${name}.exp";
1118
 
1119
            #
1120
            #   Rules and recipe to generate the stub library
1121
            #
1122
            $io->Prt( "\$(LIBDIR)/${name}.exp:\t\$(LIBDIR)/${name}.${a}\n" );
1123
            $io->Prt( "\$(LIBDIR)/${name}.${a}:\tLIBDEF=$def\n" );
1124
            $io->Prt( "\$(LIBDIR)/${name}.${a}:\tLIBNAME=$lib\n" );
1125
            $io->Entry( "\$(LIBDIR)/${name}.${a}: \\\n\t\t\$(OBJDIR)/${base}",
1126
                                            "", " \\\n\t\t", ".$::o", @$pObjs );
1127
            $io->Prt( " \\\n\t\t$def" );
1128
            $io->Prt( "\n\t\t\$(AR)\n" );
1129
            $io->Newline();
1130
 
1131
            #
1132
            #   Files to be cleanup up
1133
            #
1134
            ToolsetGenerate( "\$(LIBDIR)/${name}.exp" );
1135
            ToolsetGenerate( "\$(LIBDIR)/${name}.${a}" );
1136
 
1137
            #
1138
            #   If the DLL is being packaged/installed then add the static
1139
            #   stub library to the packaging lists as a static library
1140
            #   This will allow the stub library to be installed with the
1141
            #   static libraries and thus allow DLL's with mutual imports
1142
            #
1143
            PackageShlibAddLibFiles ($base, "\$(LIBDIR)/${name}.${a}" )
1144
                unless ($resource_only);
1145
 
1146
            #
1147
            #   Add the stub library to the list of libraries being created
1148
            #   Note: Don't do if not created with .DEF file
1149
            #
1150
            push @::LIBS, $base;
1151
 
1152
        }
1153
        else
1154
        {
1155
            #
1156
            #   The stub library is created as part of the DLL generation
1157
            #   Whether we like it or not - so we need to control the name
1158
            #   and location
1159
            #
1160
            my $slname = ($name) ? $name : $lib;
1161
            $import_lib = "\$(LIBDIR)/${slname}.${a}";
1162
 
1163
            $io->Label( "Import(stub) library", $slname );
1164
            $io->Prt( "$import_lib:\t\$(LIBDIR)/${full}\n" );
1165
            $io->Newline();
1166
 
1167
            ToolsetGenerate( $import_lib );
1168
            ToolsetGenerate( "\$(LIBDIR)/${slname}.exp" );
1169
 
1170
            #
1171
            #   Package the generated stub library, if it is being
1172
            #   created on request.
1173
            #
1174
            #   Package it with the shared libaries and not the static
1175
            #   libraries as it will be created with the shared library
1176
            #
1177
            PackageShlibAddFiles ($base, $import_lib, 'Class=lib' )
1178
                if ($name && ! $no_implib && ! $resource_only);
1179
 
1180
            #
1181
            #   Indicate that we will be linking with a DEF file
1182
            #
1183
            $link_with_def = 1 if ( $def );
1184
        }
1185
 
1186
        #
1187
        #   If we are only creating a stub library, then the hard work has been
1188
        #   done.
1189
        #
1190
        return
1191
            if ($stub_only);
1192
 
1193
        $io->Label( "Shared library", $name );
1194
 
1195
        #
1196
        #   The process of creating a DLL will generate PDB file
1197
        #   Control the name of the PDB file
1198
        #
1199
        my $pdb_file = "\$(LIBDIR)/${lib}.pdb";
1200
        unless( $no_pdb )
1201
        {
1202
            $io->Prt( "$pdb_file:\t\$(LIBDIR)/${full}\n" );
1203
            ToolsetGenerate( $pdb_file );
1204
        }
1205
 
1206
        #
1207
        #   Package the PDB file up with the DLL
1208
        #   Package the DLL - now that we know its proper name
1209
        #
1210
        PackageShlibAddFiles( $base, $pdb_file, 'Class=debug' ) unless $no_pdb ;
1211
        PackageShlibAddFiles( $base, "\$(LIBDIR)/${full}" );
1212
 
1213
        #
1214
        #   Generate Shared Library dependency information
1215
        #
1216
        $io->SHLDDEPEND( $lib, $name, $lib );   # std SHLDDEPEND rules
1217
 
1218
        #
1219
        #   Generate rules and recipes to create the body of the shared
1220
        #   library. Several build variables are overiden when creating
1221
        #   a shared library.
1222
        #
1223
        $io->Prt( "\$(LIBDIR)/${full}:\tSHBASE=${lib}\n" );
1224
        $io->Prt( "\$(LIBDIR)/${full}:\tSHNAME=${lib}\n" );
1225
        $io->Prt( "\$(LIBDIR)/${full}:\tCFLAGS+=\$(SHCFLAGS)\n" );
1226
        $io->Prt( "\$(LIBDIR)/${full}:\tCXXLAGS+=\$(SHCXXFLAGS)\n" );
1227
        $io->Prt( "\$(LIBDIR)/${full}:\t$export_file\n" ) if ($export_file );
1228
        $io->Prt( "\$(LIBDIR)/${full}:\t$res\n" ) if ( $res );
1229
 
1230
        $io->Entry( "\$(LIBDIR)/${full}: \\\n\t\t\$(OBJDIR)/${base}",
1231
            "", " \\\n\t\t", ".$::o", @$pObjs );
1232
 
1233
        $io->Prt( " \\\n\t\t$def" ) if ( $link_with_def );
1234
        $io->Prt( " \\\n\t\t\$(LIBDIR)/${lib}.dep\n" );
1235
        $io->Prt( "\t\$(SHLD)\n" );
1236
 
1237
        $io->Newline();
1238
 
1239
        #.. Linker command file
1240
        #
1241
        #       Now the fun part... piecing together a variable ${name}_shld
1242
        #       which ends up in the command file.
1243
        #
1244
        $io->SetTag( "${lib}_shld" );          # command tag
1245
 
1246
        $io->Label( "Linker commands", $name ); # label
1247
 
1248
        $io->Cmd( "-dll" );
1249
        $io->Cmd( "-noentry" )if ($resource_only);
1250
        $io->Cmd( "-def:$def" ) if ($link_with_def);
1251
        $io->Cmd( "-out:\$(subst /,\\\\,\$(LIBDIR)/${full})" );
1252
        $io->Cmd( "-implib:\$(subst /,\\\\,$import_lib)" ) if ($import_lib);
1253
        $io->Cmd( "-pdb:\$(subst /,\\\\,$pdb_file)" ) unless ( $no_pdb );
1254
        $io->Cmd( "-debug:none" )                     if ($no_pdb);
1255
        $io->Cmd( "-pdb:none" )                       if ($no_pdb);
1256
        $io->Cmd( "-entry:$entry" )                   if ($entry);
1257
        $io->Cmd( "-map:\$(subst /,\\\\,\$(LIBDIR)/${lib}).map" );
1258
        $io->Cmd( "\$(subst /,\\\\,$res)" ) if ( $res );
1259
        $io->Cmd( "\$(subst /,\\\\,$export_file)" ) if ( $export_file );
1260
 
1261
                                                # object list
1262
        $io->ObjList( $name, $pObjs, \&ToolsetObjRecipe );
1263
 
1264
                                                # library list
1265
        $io->LibList( $name, $pLibs, \&ToolsetLibRecipe );
1266
 
1267
        $io->Newline();
1268
 
1269
        #.. Dependency link,
1270
        #
1271
        #       Now piece together a variable $(name_dp) which ends up in
1272
        #       the command file building the application dependency list.
1273
        #
1274
        $io->SetTag( "${lib}_shdp" );          # command tag
1275
 
1276
        $io->DepRules( $name, $pLibs,           # library depends rules
1277
            \&ToolsetLibRecipe, "\$(LIBDIR)/${full}" );
1278
 
1279
        $io->Newline();
1280
    }
1281
 
1282
    ToolsetLibStd( $pLibs )                    # push standard libraries
1283
        unless ( $noaddlibs );
1284
 
1285
    if ( $doimplib ) {
1286
        #
1287
        #   --Implib flavor will create
1288
        #       a) Import library   $name$(GBE_TYPE).lib
1289
        #       b) Versioned DLL    $name$(GBE_TYPE).xx.xx.xx.dll
1290
        #
1291
        $target_file_dll = "\$(LIBDIR)/$name\$(GBE_TYPE).$ver.$::so";
1292
        BuildSHLD(
1293
            "$name",                        # Base Name
1294
            "$name\$(GBE_TYPE)",            # Name of Export Lib
1295
            "$name\$(GBE_TYPE).$ver");      # Name of the DLL + PDB
1296
 
1297
    } else {
1298
        #
1299
        #   Original flavor will create
1300
        #       a) Import library   $name$(GBE_TYPE).lib    ---+
1301
        #       b) Unversioned DLL  $name$(GBE_TYPE).dll    <--+
1302
        #       c) Versioned DLL    $name$(GBE_TYPE).xx.xx.xx.dll
1303
        #
1304
        MakePrint(
1305
            "# .. Versioned image\n\n".
1306
            "\$(LIBDIR)/${name}\$(GBE_TYPE).$::so:\t".
1307
            "\$(LIBDIR)/${name}\$(GBE_TYPE).$ver.$::so\n".
1308
            "\n" );
1309
 
1310
        $target_file_dll = "\$(LIBDIR)/$name\$(GBE_TYPE).$::so";
1311
        BuildSHLD( "$name", "$name\$(GBE_TYPE)" , "$name\$(GBE_TYPE)" );
1312
        BuildSHLD( "$name", ""                  , "$name\$(GBE_TYPE).$ver" );
1313
    }
1314
 
1315
    #.. Resource File
1316
    #
1317
    ToolsetRCrecipe( $res, @reslist )
1318
        if ( $res );
1319
}
1320
 
1321
 
1322
###############################################################################
1323
#   ToolsetSHLDLINT $name, \@args, \@objs, \@libraries )
1324
#       This subroutine takes the user options and builds the rules
1325
#       required to lint the program 'name'.
1326
#
1327
#   Arguments:
1328
#       (none)
1329
#
1330
#   Output:
1331
#       [ $(LIBDIR)/$name_lint:   .... ]
1332
#           $(SHLIBLINT)
1333
#
1334
###############################################################################
1335
 
1336
sub ToolsetSHLDLINT
1337
{
1338
    PCLintSHLIB( @_ );
1339
}
1340
 
1341
 
1342
###############################################################################
1343
#   ToolsetLD( $name, \@args, \@objs, \@libraries )
1344
#       This subroutine takes the user options and builds the rules
1345
#       required to link the program 'name'.
1346
#
1347
#   Arguments:
1348
#       (none)
1349
#
1350
#   Output:
1351
#       $(BINDIR)/name: \
1352
#                       OBJS .... \
1353
#                       $(BINDIR)/name.dep
1354
#           $(LD)
1355
#
1356
#       $(BINDIR)/name.dep: $(BINDIR)
1357
#       $(BINDIR)/name.dep: $(GBE_PLATFORM).mk
1358
#           $(LDDEPEND)
1359
#
1360
#       ifeq "$(IFLAG)" "3"
1361
#       -include        "$(BINDIR)/name.dep"
1362
#       endif
1363
#
1364
#       name_ld += ...
1365
#           :
1366
#
1367
#       name_dp += ...
1368
#           :
1369
#
1370
###############################################################################
1371
 
1372
sub ToolsetLD
1373
{
1374
    my ( $name, $pArgs, $pObjs, $pLibs ) = @_;
1375
    my ( $full ) = $name."$::exe";
1376
    my ( $res, @reslist );
1377
    my $no_pdb =$pdb_none;
1378
    our( $entry, $noaddlibs );
1379
 
1380
#.. Parse arguments
1381
#
1382
    foreach ( @$pArgs ) {
1383
        if (/^--Resource=(.*)/) {               # Resource definition
1384
            ($res, @reslist) = ToolsetRClist( $name, $1 );
1385
 
1386
        } elsif (/^--NoPDB$/) {
1387
            $no_pdb = 1;
1388
 
1389
        } elsif (/^--Entry=(.*)/) {
1390
            $entry = $1;
1391
 
1392
        } elsif (/^--NoAddLib/) {
1393
            $noaddlibs = 1;
1394
 
1395
        } else {
1396
            Message( "vcwce LD: unknown option $_ -- ignored\n" );
1397
 
1398
        }
1399
    }
1400
 
1401
#.. Cleanup rules
1402
#
1403
#   dep     Dependency file
1404
#   ld      Linker command file
1405
#   map     Map file
1406
#   pdb     Microsoft C/C++ program database
1407
#   ilk     Microsoft Linker Database
1408
#   res     Compiled resource script
1409
#
1410
    ToolsetGenerate( "\$(BINDIR)/${name}.dep" );
1411
    ToolsetGenerate( "\$(BINDIR)/${name}.ld" );
1412
    ToolsetGenerate( "\$(BINDIR)/${name}.map" );
1413
    ToolsetGenerate( "\$(BINDIR)/${name}.pdb" );
1414
    ToolsetGenerate( "\$(BINDIR)/${name}.ilk" );
1415
 
1416
#.. Linker command
1417
#
1418
    my ($io) = ToolsetPrinter::New();
1419
 
1420
    $io->Prt( "\\\n\t\t$res " ) if ( $res );
1421
    $io->Prt( "\\\n\t\t\$(BINDIR)/${name}.dep\n".
1422
              "\t\$(LD)\n\n" );
1423
 
1424
 
1425
    $io->LDDEPEND( $name );                     # standard LDDEPEND rules
1426
 
1427
#.. Linker command file
1428
#
1429
#       Now piece together a variable $(name_ld) which ends up in
1430
#       the command file linking the application.
1431
#
1432
    $io->SetTag( "${name}_ld" );                # macro tag
1433
 
1434
    $io->Label( "Linker commands", $name );     # label
1435
 
1436
    $io->Cmd( "-out:\$(subst /,\\\\,\$(BINDIR)/${full})" );
1437
    $io->Cmd( "-pdb:\$(subst /,\\\\,\$(BINDIR)/${name}).pdb" ) unless ($no_pdb);
1438
    $io->Cmd( "-debug:none" )                                  if ($no_pdb);
1439
    $io->Cmd( "-pdb:none" )                                    if ($no_pdb);
1440
    $io->Cmd( "-entry:$entry" )                                if ($entry);
1441
    $io->Cmd( "-map:\$(subst /,\\\\,\$(BINDIR)/${name}).map" );
1442
    $io->Cmd( "\$(subst /,\\\\,$res)" ) if ( $res );
1443
 
1444
    ToolsetLibStd( $pLibs )                     # push standard libraries
1445
        unless ( $noaddlibs );
1446
 
1447
                                                # object list
1448
    $io->ObjList( $name, $pObjs, \&ToolsetObjRecipe );
1449
 
1450
                                                # library list
1451
    $io->LibList( $name, $pLibs, \&ToolsetLibRecipe );
1452
 
1453
    $io->Newline();
1454
 
1455
#.. Dependencies
1456
#
1457
#       Now piece together a variable $(name_dp) which ends up in
1458
#       the command file building the application dependency list.
1459
#
1460
    $io->SetTag( "${name}_dp" );                # macro tag
1461
 
1462
    $io->DepRules( $name, $pLibs,               # library depends rules
1463
        \&ToolsetLibRecipe, "\$(BINDIR)/${full}" );
1464
 
1465
    $io->Newline();
1466
 
1467
#.. Compile up the resource file
1468
#
1469
    ToolsetRCrecipe( $res, @reslist )
1470
        if ( $res );
1471
 
1472
#.. Package up the PDB file with the program
1473
#
1474
    PackageProgAddFiles ( $name, "\$(BINDIR)/${name}.pdb", "Class=debug" ) unless ( $no_pdb );
1475
 
1476
#
1477
#   Track the name of the possible target file
1478
#   Used when creating Visual Studio projects
1479
#
1480
    $target_file_exe = "\$(BINDIR)/${full}";
1481
}
1482
 
1483
 
1484
###############################################################################
1485
#   ToolsetLD( $name, \@args, \@objs, \@libraries, \@csrc, \@cxxsrc )
1486
#       This subroutine takes the user options and builds the rules
1487
#       required to lint the program 'name'.
1488
#
1489
#   Arguments:
1490
#       (none)
1491
#
1492
#   Output:
1493
#       [ $(BINDIR)/$name_lint:   .... ]
1494
#           $(LDLINT)
1495
#
1496
###############################################################################
1497
 
1498
sub ToolsetLDLINT
1499
{
1500
    PCLintLD( @_ );
1501
}
1502
 
1503
 
1504
########################################################################
1505
#
1506
#   Push standard "system" libraries. This is a helper function
1507
#   used within this toolset.
1508
#
1509
#   Arguments:
1510
#       $plib       Reference to library array.
1511
#
1512
########################################################################
1513
 
1514
sub ToolsetLibStd
1515
{
1516
    my ($plib) = @_;
1517
 
1518
    #
1519
    #   Only add libraries if required
1520
    #
1521
    return unless( $::ScmCompilerOpts{'ADDLINKLIBS'} );
1522
 
1523
}
1524
 
1525
 
1526
########################################################################
1527
#
1528
#   Generate a linker object recipe.  This is a helper function used 
1529
#   within this toolset.
1530
#
1531
#   Arguments:
1532
#       $io         I/O stream
1533
#
1534
#       $target     Name of the target
1535
#
1536
#       $obj        Library specification
1537
#
1538
########################################################################
1539
 
1540
sub ToolsetObjRecipe
1541
{
1542
    my ($io, $target, $obj) = @_;
1543
 
1544
    $io->Cmd( "\$(subst /,\\\\,\$(strip $obj)).$::o" );
1545
}
1546
 
1547
 
1548
########################################################################
1549
#
1550
#   Generate a linker/depend library recipe.  This is a helper function
1551
#   used within this toolset.
1552
#
1553
#   Arguments:
1554
#       $io         I/O stream
1555
#
1556
#       $target     Name of the target
1557
#
1558
#       $lib        Library specification
1559
#
1560
#       $dp         If building a depend list, the full target name.
1561
#
1562
########################################################################
1563
 
1564
sub ToolsetLibRecipe
1565
{
1566
    my ($io, $target, $lib, $dp) = @_;
1567
 
1568
    return                                      # ignore (compat)
1569
        if ( $lib eq "rt" ||        $lib eq "thread" ||
1570
             $lib eq "pthread" ||   $lib eq "nsl" ||
1571
             $lib eq "socket" );
1572
 
1573
    if ( !defined($dp) ) {                      # linker
1574
        $io->Cmd( "\$(subst /,\\\\,\$(strip $lib)).$::a" );
1575
 
1576
    } else {                                    # depend
1577
        $io->Cmd( "$dp:\t@(vlib2,$lib,LIB)" );
1578
    }
1579
}
1580
 
1581
 
1582
########################################################################
1583
#
1584
#   Parse resource file data
1585
#   This is a helper function used within this toolset
1586
#
1587
#   Arguments   : $1  BaseName
1588
#                 $2  The users resource list
1589
#                     This is a list of comma seperated files
1590
#                     The first file is the main resource script
1591
#
1592
#   Returns     : An array of resource files with full pathnames
1593
#                 [0] = The output file
1594
#                 [1] = The input file
1595
#                 [..] = Other input files
1596
#
1597
########################################################################
1598
 
1599
sub ToolsetRClist
1600
{
1601
    my ($name, $files) = @_;
1602
    my @result;
1603
 
1604
    #
1605
    #   Generate the name of the output file
1606
    #
1607
    push @result, "\$(OBJDIR)/$name.res";
1608
 
1609
    #
1610
    #   Process each user file
1611
    #
1612
    for (split( ',', $files ))
1613
    {
1614
        #
1615
        #   Locate the file.
1616
        #   If it is a generate file so it will be in the SRCS hash
1617
        #   Other wise the use will have to use Src to locate the file
1618
        #
1619
        push @result, MakeSrcResolve($_);
1620
    }
1621
 
1622
    #
1623
    #   Return the array to the user
1624
    #
1625
    return @result;
1626
}
1627
 
1628
 
1629
########################################################################
1630
#
1631
#   Generate a resource file recipe
1632
#   This is a helper function used within this tool
1633
#
1634
#   Arguments   : $1  Output resource file
1635
#                 ..  Input resource files
1636
#
1637
########################################################################
1638
 
1639
sub ToolsetRCrecipe
1640
{
1641
    my ($out, @in) = @_;
1642
 
1643
    #
1644
    #   Cleanup
1645
    #
1646
    ToolsetGenerate( $out );
1647
 
1648
    #
1649
    #   Recipe
1650
    #
1651
    MakePrint( "\n#.. Compile Resource file: $out\n\n" );
1652
    MakePrint( "$out:\t\$(GBE_PLATFORM).mk\n" );
1653
    MakeEntry( "$out:\t", "", "\\\n\t\t", " ", @in );
1654
    MakePrint( "\n\t\$(RC)\n" );
1655
    MakePrint( "\n" );
1656
}
1657
 
1658
########################################################################
1659
#
1660
#   Generate a project from the provided project file
1661
#
1662
#   Arguments   : $name             - Base name of the project
1663
#                 $project          - Path to the project file
1664
#                 $pArgs            - Project specific options
1665
#
1666
########################################################################
1667
 
1668
my $project_defines_done = 0;
1669
sub ToolsetPROJECT
1670
{
1671
    my( $name, $project, $pArgs ) = @_;
1672
    my $buildcmd = $toolchain_info->{'buildcmd'};
1673
    my $cleancmd = $toolchain_info->{'cleancmd'};
1674
 
1675
    #
1676
    #   Process options
1677
    #
1678
    foreach ( @$pArgs ) {
1679
        Message( "vcwce PROJECT: unknown option $_ -- ignored\n" );
1680
    }
1681
    my ($io) = ToolsetPrinter::New();
1682
 
1683
    #
1684
    #   Setup toolset pecific difinitions. Once
1685
    #
1686
    unless( $project_defines_done )
1687
    {
1688
        $project_defines_done = 1;
1689
        $io->PrtLn( "ifeq \"\$(DEBUG)\" \"1\"");
1690
        $io->PrtLn( "PROJECT_CMD\t:= DEBUG");
1691
        $io->PrtLn( "else");
1692
        $io->PrtLn( "PROJECT_CMD\t:= RELEASE");
1693
        $io->PrtLn( "endif");
1694
        $io->Newline();
1695
    }
1696
 
1697
    #
1698
    #   Process the build and clean commands
1699
    #       Substitute arguments
1700
    #           =TYPE=
1701
    #           =LOG=
1702
    #           =DSW=
1703
    #           =CEPLATFORM=
1704
    #
1705
    $buildcmd =~ s~=TYPE=~\$\(PROJECT_CMD)~g;
1706
    $buildcmd =~ s~=LOG=~$name\$(GBE_TYPE).log~g;
1707
    $buildcmd =~ s~=DSW=~$project~g;
1708
    $buildcmd =~ s~=CEPLATFORM=~\$(WCE_PLATFORM)~g;
1709
 
1710
    $cleancmd =~ s~=TYPE=~\$\(PROJECT_CMD)~g;
1711
    $cleancmd =~ s~=LOG=~$name\$(GBE_TYPE).log~g;
1712
    $cleancmd =~ s~=DSW=~$project~g;
1713
    $cleancmd =~ s~=CEPLATFORM=~\$(WCE_PLATFORM)~g;
1714
 
1715
    #
1716
    #   Generate the recipe to create the project
1717
    #
1718
    $io->Label( "Build project", $name );
1719
    $io->PrtLn( "Project_$name: $project" );
1720
    $io->PrtLn( "\t\$(XX_PRE)( \$(rm) -f $name\$(GBE_TYPE).log; \\" );
1721
    $io->PrtLn( "\t\$(show_environment); \\" );
1722
    $io->PrtLn( "\t$buildcmd; \\" );
1723
    $io->PrtLn( "\tret=\$\$?; \\" );
1724
    $io->PrtLn( "\t\$(GBE_BIN)/cat $name\$(GBE_TYPE).log; \\" );
1725
    $io->PrtLn( "\texit \$\$ret )" );
1726
    $io->Newline();
1727
 
1728
    #
1729
    #   Generate the recipe to clean the project
1730
    #
1731
    $io->Label( "Clean project", $name );
1732
    $io->PrtLn( "ProjectClean_$name: $project" );
1733
    $io->PrtLn( "\t-\$(XX_PRE)$cleancmd" );
1734
    $io->PrtLn( "\t-\$(XX_PRE)\$(rm) -f $name\$(GBE_TYPE).log" );
1735
    $io->Newline();
1736
 
1737
}
1738
 
1739
 
1740
#.. Successful termination
1741
1;
1742