Subversion Repositories DevTools

Rev

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

Rev Author Line No. Line
227 dpurdie 1
#
2
# Module name   : vcwin32
3
# Module type   : Makefile system
4
# Compiler(s)   : ANSI C
5
# Environment(s): WIN32
6
#
7
# Description:
8
#       Visual C/C++ for WIN32
9
#
10
#............................................................................#
11
 
12
use strict;
13
use warnings;
14
 
15
#
16
#   Global data
17
#
18
my $pdb_file = "\$(GBE_PBASE)";
19
my $pdb_first_lib;
20
my $target_file_lib;
21
my $target_file_dll;
22
my $target_file_exe;
23
my $pdb_none;
24
 
25
##############################################################################
26
#   Version information
27
#
28
my $toolset_info;
29
my $toolset_version = 'MSVC6';
30
my %ToolsetVersion =
31
    (
32
        'MSVC6'      =>  { 'def'      => 'vcwin32.def' ,
33
                           'buildcmd' => 'msdev =DSW= /make "ALL - =TYPE=" /useenv /out =LOG=' ,
34
                           'cleancmd' => 'msdev =DSW= /make "ALL - =TYPE=" /clean /useenv' ,
35
                           'tmp'      => 'vc60'},
36
 
37
        'MS.NET2003' =>  { 'def'      => 'vcwin32_net2003.def' ,
38
                           'buildcmd' => 'devenv =DSW= /build =TYPE= /useenv /out =LOG=' ,
39
                           'cleancmd' => 'devenv =DSW= /clean =TYPE= /useenv' ,
40
                           'tmp'      => 'vc70'},
41
    );
42
 
43
 
44
##############################################################################
45
#   ToolsetInit()
46
#       Runtime initialisation
47
#
48
##############################################################################
49
 
50
ToolsetInit();
51
 
52
sub ToolsetInit
53
{
54
 
55
#.. Parse arguments (Toolset arguments)
56
#
57
    Debug( "vcwin32(@::ScmToolsetArgs)" );
58
 
59
    foreach $_ ( @::ScmToolsetArgs ) {
60
        if (/^--Version=(.*)/) {           # MS SDK Version
61
            $toolset_version = $1;
62
 
63
        } else {
64
            Message( "vcwin32 toolset: unknown option $_ -- ignored\n" );
65
        }
66
    }
67
 
68
#.. Parse arguments (platform arguments)
69
#
70
    Debug( "vcwin32(@::ScmPlatformArgs)" );
71
 
72
    foreach $_ ( @::ScmPlatformArgs ) {
73
        if (/^--product=(.*)/) {                # GBE product
74
 
75
        } elsif (/^--Version=(.*)/) {           # MS SDK Version
76
            $toolset_version = $1;
77
 
78
        } elsif (/^--NoDinkumware/) {           # Dinkumware package test
79
 
80
        } else {
81
            Message( "vcwin32 toolset: unknown platform argument $_ -- ignored\n" );
82
        }
83
    }
84
 
85
#.. Validate SDK version
86
#   Currently two versions are supported
87
#       1) MSVC6            - As provided via Visual Studio
88
#       2) MSVS.net 2003    - Used to create .NET applications
89
#
90
    $toolset_info = $ToolsetVersion{$toolset_version};
91
    Error( "Unknown version: $toolset_version" ) unless ( defined $toolset_info );
92
 
93
 
94
#.. Standard.rul requirements
95
#
96
    $::s = 'asm';
97
    $::o = 'obj';
98
    $::a = 'lib';
99
    $::so = 'dll';
100
    $::exe = '.exe';
101
 
102
#.. Toolset configuration
103
#
104
    $::ScmToolsetVersion = "1.0.0";             # our version
105
    $::ScmToolsetGenerate = 0;                  # generate optional
106
    $::ScmToolsetIFLAG3 = 1;                    # supports IFLAG3
107
 
108
#.. define Visual C/C+ environment
109
    Init( "visualc" );
110
    ToolsetDefines( $toolset_info->{'def'} );
111
    ToolsetRequire( "exctags" );                # and Exuberant Ctags
112
    ToolsetRules( "vcwin32.rul" );
113
    ToolsetRules( "standard.rul" );
114
 
115
#.. define PCLint envrionment
116
    ToolsetRequire( "pclint" );                 # using pclint
117
    PlatformDefine ("LINT_COFILE\t= co-msc60.lnt");
118
    PlatformDefine ("LINT_PRJ_FILE\t=lint.visualc");
119
 
120
#.. Cleanup rules
121
#
122
    ToolsetGenerate( "\$(OBJDIR)/$toolset_info->{'tmp'}.idb" );     # vc60.idb
123
    ToolsetGenerate( "\$(OBJDIR)/$toolset_info->{'tmp'}.pch" );
124
    ToolsetGenerate( "\$(OBJDIR)/$toolset_info->{'tmp'}.pdb" );
125
    ToolsetGenerate( "\$(PDB)" );
126
    ToolsetGenerate( "\$(PDB).tmp" );
127
 
128
 
129
#
130
#   The PDB files need to be compiled up with absolute paths to the source files
131
#   The easiest way to do this is with the makefile rules created with absolute
132
#   paths. Set a global flag to enable this option
133
#
134
    $::UseAbsObjects = 1;
135
 
136
 
137
#.. Extend the CompilerOption directive
138
#   Create a standard data structure
139
#   This is a hash of hashes
140
#       The first hash is keyed by CompileOption keyword
141
#       The second hash contains pairs of values to set or remove
142
#
143
    %::ScmToolsetCompilerOptions =
144
    (
145
        #
146
        #   Control the thread model to use
147
        #   This will affect the compiler options and the linker options
148
        #
149
        'multithread_static' => { 'THREADMODE' , 'T' },      # -MT
150
        'multithread_dll'    => { 'THREADMODE' , 'D' },      # -MD Default
151
        'multithread_none'   => { 'THREADMODE' , 'L' },      # -ML
152
 
153
        'subsystem:windows'  => { 'LDSUBSYSTEM' , 'windows' },
154
        'subsystem:console'  => { 'LDSUBSYSTEM' , 'console' },
155
 
156
        'rtti'               => { 'USE_RTTI', 1 },
157
        'nopdb'              => { 'PDB_NONE', 1 },
158
        'pdb'                => { 'PDB_NONE', undef },
159
        'noaddlibs'          => { 'ADDLINKLIBS' , undef },      # Don't add link libs
160
        'addlibs'            => { 'ADDLINKLIBS' , '1' },        # default
161
        'noprecompilehdrs'   => { 'PRECOMPILEHDRS' , undef },   # Don't precompile headers
162
        'precompilehdrs'     => { 'PRECOMPILEHDRS' , '1' },     # default
163
 
164
        #
165
        #   Mimic some of the behavior of version-1 JATS
166
        #
167
        'jats_v1'            => { 'USE_JATS_V1' => '1' },
168
    );
169
 
170
    #
171
    #   Set default options
172
    #
173
    $::ScmCompilerOpts{'THREADMODE'} = 'D';
174
    $::ScmCompilerOpts{'ADDLINKLIBS'} = '1';
175
    $::ScmCompilerOpts{'PRECOMPILEHDRS'} = '1';
176
}
177
 
178
##############################################################################
179
#   ToolsetPreprocess()
180
#       Process collected data before the makefile is generated
181
#       This, optional, routine is called from within MakefileGenerate()
182
#       It allows the toolset to massage any of the collected data before
183
#       the makefile is created
184
#
185
##############################################################################
186
sub ToolsetPreprocess
187
{
188
    #
189
    #   Extract the current state of PDB_NONE
190
    #   Are PDB files to be constructed.
191
    #
192
    $pdb_none = $::ScmCompilerOpts{'PDB_NONE'};
193
}
194
 
195
##############################################################################
196
#   ToolsetPostprocess
197
#       Process collected data as the makefile is generated
198
#       This, optional, routine is called from within MakefileGenerate()
199
#       It allows the toolset to massage any of the collected data before
200
#       the makefile is finally closed created
201
#
202
##############################################################################
203
 
204
sub ToolsetPostprocess
205
{
206
 
207
    #
208
    #   Specify the name of the global PDB file. This is used for all
209
    #   compiles other than those associated with building a DLL
210
    #
211
    #   The name of the PDB will be based on either
212
    #       The name of base package
213
    #       The name of the first static library created
214
    #
215
 
216
MakePrint("
217
#--------- Toolset Postprocessed Information --------------------------------
218
#
219
#   Export the name of the common PDB file
220
#   All compiler information will be placed in this file
221
#   The name of the file MUST be the same as the name of the output library
222
#
223
PDB		= \$(OBJDIR)/$pdb_file\$(GBE_TYPE).pdb
224
" );
225
 
226
    #
227
    #   Add values to the perl environment
228
    #   May be used by post processing tools to create Visual Studio Projects
229
    #
230
    $::TS_pdb_file = "\$(OBJDIR)/$pdb_file\$(GBE_TYPE).pdb" unless( $pdb_none );
231
    $::TS_sbr_support = 1;
232
 
233
    #
234
    #   Prioritorise target: EXE, DLL, LIB
235
    #
236
    for my $tgt ( $target_file_exe, $target_file_dll, $target_file_lib  )
237
    {
238
        if ( $tgt )
239
        {
240
            $::TS_target_file = $tgt;
241
            last;
242
        }
243
    }
244
}
245
 
246
 
247
###############################################################################
248
#   ToolsetCTAGS()
249
#       This subroutine takes the user options and builds the rules
250
#       required to build the CTAGS database.
251
#
252
#   Arguments:
253
#       --xxx                   No arguments currently defined
254
#
255
#   Output:
256
#       [ctags:]
257
#           $(EXCTAGS)
258
#
259
###############################################################################
260
 
261
sub ToolsetCTAGS
262
{
263
    EXCTAGS( @_ );
264
}
265
 
266
 
267
###############################################################################
268
#   ToolsetCC( $source, $obj, \@args )
269
#       This subroutine takes the user options and builds the rule(s)
270
#       required to compile the source file 'source' to 'obj'
271
#
272
###############################################################################
273
 
274
sub ToolsetCC
275
{
276
    ToolsetCC_common( "CC", @_ );
277
}
278
 
279
sub ToolsetCC_common
280
{
281
    my( $name, $source, $obj, $pArgs ) = @_;
282
    my( $cflags, $pdb );
283
 
284
    foreach $_ ( @$pArgs ) {
285
        if (/--Shared$/) {                      # Building a 'shared' object
286
            $cflags = "$cflags \$(SHCFLAGS)";
287
            $pdb = $::SHOBJ_LIB{$obj}
288
                if (exists $::SHOBJ_LIB{$obj} );
289
 
290
        } else {
291
            Message( "vcwin32 $name: unknown option $_ -- ignored\n" );
292
        }
293
    }
294
 
295
    MakePrint( "\n\t\$($name)\n" );
296
    MakePadded( 4, "\$(OBJDIR)/$obj.$::o:", "\tCFLAGS +=$cflags\n" )
297
        if ( $cflags );                         # object specific CFLAGS
298
 
299
    if ( $pdb && !$pdb_none )
300
    {
301
        #
302
        #   Determine the name of the PDB file
303
        #   If we are building a shared library then the name of the PDB
304
        #   MUST NOT be the same as the name of the library as there is
305
        #   some stange interaction with the linker ( 50% of the time )
306
        #   This is OK as the file will not be published
307
        #
308
        #   If building a static library then create a PDB of the same
309
        #   name as it may be published directly.
310
        #
311
        my $pdb_file;
312
        if ($cflags )
313
        {
314
            $pdb_file = "\$(OBJDIR)/${pdb}\$(GBE_TYPE)_shlib.pdb";
315
        }
316
        else
317
        {
318
            $pdb_file = "\$(OBJDIR)/${pdb}\$(GBE_TYPE).pdb";
319
        }    
320
 
321
        MakePadded( 4, "\$(OBJDIR)/$obj.$::o:", "\tPDB = $pdb_file\n" );
322
        ToolsetGenerate( $pdb_file );
323
        ToolsetGenerate( $pdb_file . ".tmp" );
324
    }
325
 
326
    #
327
    #   Remove possible Source Browser Files
328
    #
329
    ToolsetGenerate( "\$(OBJDIR)/$obj.sbr" );
330
    MakePrint( "\n" );
331
}
332
 
333
 
334
###############################################################################
335
#   ToolsetCCDepend( $depend, \@sources )
336
#       This subroutine takes the user options and builds the
337
#       rule(s) required to build the dependencies for the source
338
#       files 'sources' to 'depend'.
339
#
340
###############################################################################
341
 
342
sub ToolsetCCDepend
343
{
344
    MakePrint( "\t\$(CCDEPEND)\n" );
345
}
346
 
347
 
348
###############################################################################
349
#   ToolsetCXX( $source, $obj, \@args )
350
#       This subroutine takes the user options and builds the rule(s)
351
#       required to compile the source file 'source' to 'obj'
352
#
353
###############################################################################
354
 
355
sub ToolsetCXX
356
{
357
    ToolsetCC_common( "CXX", @_ );
358
}
359
 
360
###############################################################################
361
#   ToolsetCXXDepend( $depend, \@sources )
362
#       This subroutine takes the user options and builds the
363
#       rule(s) required to build the dependencies for the source
364
#       files 'sources' to 'depend'.
365
#
366
###############################################################################
367
 
368
sub ToolsetCXXDepend
369
{
370
    MakePrint( "\t\$(CCDEPEND)\n" );
371
}
372
 
373
 
374
###############################################################################
375
#   ToolsetAS( $source, $obj, \@args )
376
#       This subroutine takes the user options and builds the rule(s)
377
#       required to compile the source file 'source' to 'obj'
378
#
379
###############################################################################
380
 
381
sub ToolsetAS
382
{
383
    MakePrint( "\n\t\$(AS)\n" );
384
}
385
 
386
sub ToolsetASDepend
387
{
388
}
389
 
390
###############################################################################
391
#   ToolsetAR( $name, \@args, \@objs )
392
#       This subroutine takes the user options and builds the rules
393
#       required to build the library 'name'.
394
#
395
#   Arguments:
396
#       --Def=name              Library definition module
397
#
398
#   Output:
399
#       [ $(LIBDIR)/name$.${a}:   .... ]
400
#           $(AR)
401
#
402
###############################################################################
403
 
404
sub ToolsetAR
405
{
406
    my( $name, $pArgs, $pObjs ) = @_;
407
    my( $def );
408
    my ( $res, @reslist );
409
    my $lib_base = "\$(LIBDIR)/${name}\$(GBE_TYPE)";
410
    my $lib_name = "$lib_base.${a}";
411
 
412
 
413
#.. Parse arguments
414
#
415
    $def = "";                                  # options
416
    $res = "";
417
 
418
    foreach $_ ( @$pArgs ) {
419
        if (/^--Def=(.*)/) {                    # library definition
420
            $def = "$1";
421
 
422
        } elsif (/^--Resource=(.*)/) {          # Resource definition
423
            ($res, @reslist) = ToolsetRClist( "$name", $1 );
424
 
425
        } else {                                # unknown
426
            Message( "vcwin32 AR: unknown option $_ -- ignored\n" );
427
        }
428
    }
429
 
430
#.. Resource Creation
431
#
432
    MakePrint( "#.. Library Resource ($name)\n\n" );
433
    ToolsetRCrecipe( $res, @reslist )
434
        if ( $res );
435
 
436
#.. Target
437
#
438
    MakePrint( "#.. Library ($name)\n\n" );     # label
439
 
440
    MakePrint( "$lib_name:\tLIBDEF=$def\n" ) if ($def);
441
    MakeEntry( "$lib_name:\t", "", "\\\n\t\t", ".$::o", @$pObjs );
442
    MakePrint( "\\\n\t\t$def" ) if ($def);
443
    MakePrint( "\\\n\t\t$res" ) if ($res);
444
    MakePrint( "\n\t\$(AR)" );
445
 
446
#
447
#   Track the name of the possible target file
448
#   Used when creating Visual Studio projects
449
#
450
    $target_file_lib = $lib_name;
451
 
452
#
453
#   To assist in debugging the static library it is nice to
454
#   keep the PDB file used to build the library, with the library.
455
#
456
#   If the library is being packaged or installed then add the PDB
457
#   file to the package / installation
458
#
459
#   NOTE: Due to the limitations of JATS/MicroSoft only one static
460
#   library can be built with a PDB file. The name of the PDB file
461
#   will be taken from the first static library encountered
462
#
463
    unless ( $pdb_first_lib )
464
    {
465
        $pdb_first_lib = $name;
466
        $pdb_file = $name;
467
    }
468
    else
469
    {
470
        Warning( "Multiple static libraries created with a common PDB file: $pdb_file, $name" )
471
            unless( $pdb_none );
472
    }
473
 
474
    PackageLibAddFiles( $name, "\$(OBJDIR)/$pdb_file\$(GBE_TYPE).pdb", "Class=debug" )
475
        unless( $pdb_none );
476
}
477
 
478
 
479
###############################################################################
480
#   ToolsetARLINT( $name, \@args, \@objs )
481
#       This subroutine takes the user options and builds the rules
482
#       required to build the library 'name'.
483
#
484
#   Arguments:
485
#       --xxx                   No arguments currently defined
486
#
487
#   Output:
488
#       [ $(LIBDIR)/name$_lint:   .... ]
489
#           $(ARLINT)
490
#
491
###############################################################################
492
 
493
sub ToolsetARLINT
494
{
495
    PCLintAR( @_ );
496
}
497
 
498
 
499
###############################################################################
500
#   ToolsetARMerge( $name, \@args, \@libs )
501
#       This subroutine takes the user options and builds the rules
502
#       required to build the library 'name' by merging the specified
503
#       libaries
504
#
505
#   Arguments:
506
#       --xxx                   No arguments currently defined
507
#
508
#   Output:
509
#       [ $(LIBDIR)/name$.${a}:   .... ]
510
#           ...
511
#
512
###############################################################################
513
 
514
sub ToolsetARMerge
515
{
516
    my ($name, $pArgs, $pLibs) = @_;
517
    MakePrint( "\n\t\$(ARMERGE)\n\n" );
518
 
519
    #
520
    #   Package up the PDB's with the library
521
    #   Note: The PDBs will be found in the OBJDIR
522
    #
523
    unless( $pdb_none )
524
    {
525
        for ( @{$pLibs} )
526
        {
527
            s~\$\(LIBDIR\)~\$(OBJDIR)~;
528
            PackageLibAddFiles( $name, "$_\$(GBE_TYPE).pdb", "Class=debug" );
529
        }
530
    }
531
}
532
 
533
 
534
###############################################################################
535
#   ToolsetSHLD $name, \@args, \@objs, \@libraries )
536
#       This subroutine takes the user options and builds the rules
537
#       required to link a shared library
538
#
539
#   Arguments:
540
#       --Def=xxxx.def[,opts]           # Definition file
541
#           --MutualDll                 # SubOption: Generate a Mutual DLL
542
#       --MutualDll                     # Generate a Mutual DLL (requires --Def=xxx)
543
#       --StubOnly                      # Only generate the stub library (requires --Def=xxx)
544
#       --Resource=xxxx.rc              # Resource file
545
#       --ResourceOnly                  # Only resources in this DLL
546
#       --Implib                        # Alternate ruleset
547
#       --NoPDB                         # Do not package the PDB file
548
#       --NoImplib                      # Do not package the import library
549
#       --Entry=xxxxx                   # Entry point
550
#       --NoAddLibs                     # Do not add libraries
551
#
552
#   Output:
553
#
554
#       There is two supported rule sets differentiated by --Implib
555
#       The two are very similar and generated exportable files of:
556
#
557
#       --Implib
558
#           ${name}.lib         - Stub lib adresses the versioned DLL
559
#           ${name}.${ver}.dll
560
#
561
#       Default
562
#           ${name}.lib         - Stub lib addresses UN-versioned DLL
563
#           ${name}.dll
564
#           ${name}.${ver}.dll
565
#
566
#       Note: Each DLL has an associated PDB file
567
#
568
#       Generation is identical for both rulesets. The default form does
569
#       not export any stub library associated with the versioned DLL.
570
#
571
#   Implementation notes
572
#   The process of creating a DLL and associated import library (LIB) is
573
#
574
#           ${name}.${ver}.dep
575
#           ${name}.${ver}.pdb          - Exported
576
#           ${name}.${ver}.ilk
577
#           ${name}.${ver}.dll          - Exported
578
#           ${name}.${ver}.map
579
#           ${name}.lib                 - Exported + Optional
580
#           ${name}.exp
581
#
582
#       Where:    lib = name
583
#
584
#       #.. Rules ($lib)
585
#
586
#       $(LIBDIR)/${lib}.lib:               $(LIBDIR)/${lib}.${ver}.dll
587
#       $(LIBDIR)/${lib}.pdb:               $(LIBDIR)/${lib}.${ver}.dll
588
#       $(LIBDIR)/${lib}.${ver}.pdb:        $(LIBDIR)/${lib}.${ver}.dll
589
#
590
#       $(LIBDIR)/${lib}.${ver}.dep:        SHBASE=${name}
591
#       $(LIBDIR)/${lib}.${ver}.dep:        SHNAME=${lib}.${ver}
592
#       $(LIBDIR)/${lib}.${ver}.dep:        \$(LIBDIR)
593
#       $(LIBDIR)/${lib}.${ver}.dep:        Makefile
594
#           $(SHLDDEPEND)
595
#
596
#       $(LIBDIR)/${lib}.${ver}.${so}:      SHBASE=${name}
597
#       $(LIBDIR)/${lib}.${ver}.${so}:      SHNAME=${lib}.${ver}
598
#       $(LIBDIR)/${lib}.${ver}.${so}:      CFLAGS+=$(SHCFLAGS)
599
#       $(LIBDIR)/${lib}.${ver}.${so}:      CXXLAGS+=$(SHCXXFLAGS)
600
#       $(LIBDIR)/${lib}.${ver}.${so}:      ${def}
601
#       $(LIBDIR)/${lib}.${ver}.${so}:      $(OBJDIR)/${name} \
602
#                       object list ... \
603
#                       $(LIBDIR)/${lib}.${ver}.dep
604
#           $(SHLD)
605
#           @$(cp) -f $(LIBDIR)/${lib}.${ver}.pdb $(LIBDIR)/${lib}.pdb
606
#
607
#       ifneq "$(findstring $(IFLAG),23)" ""
608
#       -include        "$(LIBDIR)/${lib}.${ver}.dep"
609
#       endif
610
#
611
#       #.. Linker commands ($lib)
612
#
613
#       ${lib}_ld       += ...
614
#               standard flags                          \
615
#               -implib:$${lib}.lib
616
#
617
#       #.. Linker commands ($lib)
618
#
619
#       ${lib}_shdp     += ...
620
#
621
###############################################################################
622
 
623
sub ToolsetSHLD
624
{
625
    our( $name, $pArgs, $pObjs, $pLibs ) = @_;
626
    our( $def, $mutual_dll, $res, @reslist, $doimplib, $stub_only );
627
    our( $no_implib, $no_pdb, $resource_only );
628
    our( $entry, $noaddlibs );
629
 
630
#.. Parse arguments
631
#
632
    $def = "";                                  # options
633
    $doimplib = 0;
634
    $res = "";
635
    $no_pdb = $pdb_none;
636
 
637
    foreach $_ ( @$pArgs ) {
638
        if (/^--Def=(.*?)(\,(.*))?$/) {         # Library definition
639
            #
640
            #   Locate the Def file.
641
            #   If it is a generate file so it will be in the SRCS hash
642
            #   Otherwise the user will have to use Src to locate the file
643
            #
644
            $def = MakeSrcResolve($1);
645
 
646
            #
647
            #   Process sub options to --Def
648
            #
649
            next unless ($2);
650
            if ( $3 =~ /^--MutualDll$/ ) {
651
                $mutual_dll = 1;
652
            } else {
653
                Message( "vcwin32 SHLD: unknown option $_ -- ignored\n" );
654
            }
655
 
656
        } elsif (/^--Resource=(.*)/) {          # Resource definition
657
            ($res, @reslist) = ToolsetRClist( "$name/$name", $1 );
658
 
659
        } elsif (/^--ResourceOnly/) {          # Resource definition
660
            $resource_only = 1;
661
 
662
        } elsif (/^--Implib$/) {
663
            $doimplib = 1;
664
 
665
        } elsif (/^--NoImplib$/) {
666
            $no_implib = 1;
667
 
668
        } elsif (/^--NoPDB$/) {
669
            $no_pdb = 1;
670
 
671
        } elsif (/^--Entry=(.*)/) {
672
            $entry = $1;
673
 
674
        } elsif (/^--NoAddLib/) {
675
            $noaddlibs = 1;
676
 
677
        } elsif (/^--MutualDll$/) {
678
            $mutual_dll = 1;
679
 
680
        } elsif (/^--Stubonly/) {
681
            $stub_only = 1;
682
        } else {                                # unknown
683
            Message( "vcwin32 SHLD: unknown option $_ -- ignored\n" );
684
        }
685
    }
686
 
687
    #
688
    #   Sanity test
689
    #
690
    Error ("vcwin32 SHLD:Stubonly option requires --Def=file ")
691
        if ( $stub_only && ! $def );
692
 
693
    Error ("vcwin32 SHLD:MutualDll option requires --Def=file ")
694
        if ( $mutual_dll && ! $def );
695
 
696
 
697
 
698
#.. Build rules
699
#
700
#   base    -   Basic name of the DLL
701
#   name    -   Name of the Export library (Optional)
702
#   lib     -   Name of the DLL
703
#
704
    sub BuildSHLD
705
    {
706
        my ($base, $name, $lib) = @_;
707
        my $full = $lib.".$::so";
708
        my $link_with_def;
709
 
710
    #.. Cleanup rules
711
    #
712
    #   dep     Dependency file
713
    #   ld      Linker command file
714
    #   map     Map file
715
    #   pdb     Microsoft C/C++ program database
716
    #   ilk     Microsoft Linker Database
717
    #
718
        ToolsetGenerate( "\$(LIBDIR)/${lib}.ld" );
719
        ToolsetGenerate( "\$(LIBDIR)/${lib}.dep" );
720
        ToolsetGenerate( "\$(LIBDIR)/${lib}.map" );
721
        ToolsetGenerate( "\$(LIBDIR)/${lib}.exp" );
722
        ToolsetGenerate( "\$(LIBDIR)/${lib}.ilk" );
723
        ToolsetGenerate( "\$(LIBDIR)/${full}" );
724
 
725
    #.. Linker rules
726
    #
727
        my ($io) = ToolsetPrinter::New();
728
 
729
        my $import_lib;
730
        my $export_file;
731
 
732
        if ( $name && $def && ($mutual_dll || $stub_only ) )
733
        {
734
            #
735
            #   Creating an Export library from user .DEF file
736
            #   It is possible to create the stub library in the LIB phase
737
            #   which allows DLLs with mutual imports
738
            #
739
            $io->Label( "Import(stub) library for mutual exports", $name );
740
            $export_file = "\$(LIBDIR)/${name}.exp";
741
 
742
            #
743
            #   Rules and recipe to generate the stub library
744
            #
745
            $io->Prt( "\$(LIBDIR)/${name}.exp:\t\$(LIBDIR)/${name}.${a}\n" );
746
            $io->Prt( "\$(LIBDIR)/${name}.${a}:\tLIBDEF=$def\n" );
747
            $io->Prt( "\$(LIBDIR)/${name}.${a}:\tLIBNAME=$lib\n" );
748
            $io->Entry( "\$(LIBDIR)/${name}.${a}: \\\n\t\t\$(OBJDIR)/${base}",
749
                                            "", " \\\n\t\t", ".$::o", @$pObjs );
750
            $io->Prt( " \\\n\t\t$def" );
751
            $io->Prt( "\n\t\t\$(AR)\n" );
752
            $io->Newline();
753
 
754
            #
755
            #   Files to be cleanup up
756
            #
757
            ToolsetGenerate( "\$(LIBDIR)/${name}.exp" );
758
            ToolsetGenerate( "\$(LIBDIR)/${name}.${a}" );
759
 
760
            #
761
            #   If the DLL is being packaged/installed then add the static
762
            #   stub library to the packaging lists as a static library
763
            #   This will allow the stub library to be installed with the
764
            #   static libraries and thus allow DLL's with mutual imports
765
            #
766
            PackageShlibAddLibFiles ($base, "\$(LIBDIR)/${name}.${a}" )
767
                unless ($resource_only);
768
 
769
            #
770
            #   Add the stub library to the list of libraries being created
771
            #   Note: Don't do if not created with .DEF file
772
            #
773
            push @::LIBS, $base;
774
 
775
        }
776
        else
777
        {
778
            #
779
            #   The stub library is created as part of the DLL generation
780
            #   Whether we like it or not - so we need to control the name
781
            #   and location
782
            #
783
            my $slname = ($name) ? $name : $lib;
784
            $import_lib = "\$(LIBDIR)/${slname}.${a}";
785
 
786
            $io->Label( "Import(stub) library", $slname );
787
            $io->Prt( "$import_lib:\t\$(LIBDIR)/${full}\n" );
788
            $io->Newline();
789
 
790
            ToolsetGenerate( $import_lib );
791
            ToolsetGenerate( "\$(LIBDIR)/${slname}.exp" );
792
 
793
            #
794
            #   Package the generated stub library, if it is being
795
            #   created on request.
796
            #
797
            #   Package it with the shared libaries and not the static
798
            #   libraries as it will be created with the shared library
799
            #
800
            PackageShlibAddFiles ($base, $import_lib, 'Class=lib' )
801
                if ($name && ! $no_implib && ! $resource_only);
802
 
803
            #
804
            #   Indicate that we will be linking with a DEF file
805
            #
806
            $link_with_def = 1 if ( $def );
807
        }
808
 
809
        #
810
        #   If we are only creating a stub library, then the hard work has been
811
        #   done.
812
        #
813
        return
814
            if ($stub_only);
815
 
816
        $io->Label( "Shared library", $name );
817
 
818
        #
819
        #   The process of creating a DLL will generate PDB file
820
        #   Control the name of the PDB file
821
        #
822
        my $pdb_file = "\$(LIBDIR)/${lib}.pdb";
823
        unless( $no_pdb )
824
        {
825
            $io->Prt( "$pdb_file:\t\$(LIBDIR)/${full}\n" );
826
            ToolsetGenerate( $pdb_file );
827
        }
828
 
829
        #
830
        #   Package the PDB file up with the DLL
831
        #   Package the DLL - now that we know its proper name
832
        #
833
        PackageShlibAddFiles( $base, $pdb_file, 'Class=debug' ) unless $no_pdb ;
834
        PackageShlibAddFiles( $base, "\$(LIBDIR)/${full}" );
835
 
836
        #
837
        #   Generate Shared Library dependency information
838
        #
839
        $io->SHLDDEPEND( $lib, $name, $lib );   # std SHLDDEPEND rules
840
 
841
        #
842
        #   Generate rules and recipes to create the body of the shared
843
        #   library. Several build variables are overiden when creating
844
        #   a shared library.
845
        #
846
        $io->Prt( "\$(LIBDIR)/${full}:\tSHBASE=${lib}\n" );
847
        $io->Prt( "\$(LIBDIR)/${full}:\tSHNAME=${lib}\n" );
848
        $io->Prt( "\$(LIBDIR)/${full}:\tCFLAGS+=\$(SHCFLAGS)\n" );
849
        $io->Prt( "\$(LIBDIR)/${full}:\tCXXLAGS+=\$(SHCXXFLAGS)\n" );
850
        $io->Prt( "\$(LIBDIR)/${full}:\t$export_file\n" ) if ($export_file );
851
        $io->Prt( "\$(LIBDIR)/${full}:\t$res\n" ) if ( $res );
852
 
853
        $io->Entry( "\$(LIBDIR)/${full}: \\\n\t\t\$(OBJDIR)/${base}",
854
            "", " \\\n\t\t", ".$::o", @$pObjs );
855
 
856
        $io->Prt( " \\\n\t\t$def" ) if ( $link_with_def );
857
        $io->Prt( " \\\n\t\t\$(LIBDIR)/${lib}.dep\n" );
858
        $io->Prt( "\t\$(SHLD)\n" );
859
 
860
        $io->Newline();
861
 
862
        #.. Linker command file
863
        #
864
        #       Now the fun part... piecing together a variable ${name}_shld
865
        #       which ends up in the command file.
866
        #
867
        $io->SetTag( "${lib}_shld" );          # command tag
868
 
869
        $io->Label( "Linker commands", $name ); # label
870
 
871
        $io->Cmd( "-dll" );
872
        $io->Cmd( "-noentry" )if ($resource_only);
873
        $io->Cmd( "-machine:IX86" );
874
        $io->Cmd( "-base:0x10000000" );
875
        $io->Cmd( "-def:$def" ) if ($link_with_def);
876
        $io->Cmd( "-out:\$(subst /,\\\\,\$(LIBDIR)/${full})" );
877
        $io->Cmd( "-implib:\$(subst /,\\\\,$import_lib)" ) if ($import_lib);
878
        $io->Cmd( "-pdb:\$(subst /,\\\\,$pdb_file)" )       unless ( $no_pdb );
879
        $io->Cmd( "-debug:none" )                           if ($no_pdb);
880
        $io->Cmd( "-pdb:none" )                             if ($no_pdb);
881
        $io->Cmd( "-entry:$entry" )                         if ($entry);
882
        $io->Cmd( "-map:\$(subst /,\\\\,\$(LIBDIR)/${lib}).map" );
883
        $io->Cmd( "-nodefaultlib:LIBC" );
884
        $io->Cmd( "\$(subst /,\\\\,$res)" ) if ( $res );
885
        $io->Cmd( "\$(subst /,\\\\,$export_file)" ) if ( $export_file );
886
 
887
                                                # object list
888
        $io->ObjList( $name, $pObjs, \&ToolsetObjRecipe );
889
 
890
                                                # library list
891
        $io->LibList( $name, $pLibs, \&ToolsetLibRecipe );
892
 
893
        $io->Newline();
894
 
895
        #.. Dependency link,
896
        #
897
        #       Now piece together a variable $(name_dp) which ends up in
898
        #       the command file building the application dependency list.
899
        #
900
        $io->SetTag( "${lib}_shdp" );          # command tag
901
 
902
        $io->DepRules( $name, $pLibs,           # library depends rules
903
            \&ToolsetLibRecipe, "\$(LIBDIR)/${full}" );
904
 
905
        $io->Newline();
906
    }
907
 
908
    ToolsetLibStd( $pLibs )                    # push standard libraries
909
        unless ( $noaddlibs );
910
 
911
    if ( $doimplib ) {
912
        #
913
        #   --Implib flavor will create
914
        #       a) Import library   $name$(GBE_TYPE).lib
915
        #       b) Versioned DLL    $name$(GBE_TYPE).xx.xx.xx.dll
916
        #
917
        $target_file_dll = "\$(LIBDIR)/$name\$(GBE_TYPE).$::SHLIB_VER{ $name }.$::so";
918
        BuildSHLD(
919
            "$name",                                    # Base Name
920
            "$name\$(GBE_TYPE)",                        # Name of Export Lib
921
            "$name\$(GBE_TYPE).$::SHLIB_VER{ $name }"); # Name of the DLL + PDB
922
 
923
    } else {
924
        #
925
        #   Original flavor will create
926
        #       a) Import library   $name$(GBE_TYPE).lib    ---+
927
        #       b) Unversioned DLL  $name$(GBE_TYPE).dll    <--+
928
        #       c) Versioned DLL    $name$(GBE_TYPE).xx.xx.xx.dll
929
        #
930
        MakePrint(
931
            "# .. Versioned image\n\n".
932
            "\$(LIBDIR)/${name}\$(GBE_TYPE).$::SHLIB_VER{ $name }.$::so:\t".
933
            "\$(LIBDIR)/${name}\$(GBE_TYPE).$::so\n".
934
            "\n" );
935
 
936
        $target_file_dll = "\$(LIBDIR)/$name\$(GBE_TYPE).$::so";
937
        BuildSHLD( "$name", ""                  , "$name\$(GBE_TYPE).$::SHLIB_VER{ $name }" );
938
        BuildSHLD( "$name", "$name\$(GBE_TYPE)" , "$name\$(GBE_TYPE)" );
939
    }
940
 
941
    #.. Resource File
942
    #
943
    ToolsetRCrecipe( $res, @reslist )
944
        if ( $res );
945
}
946
 
947
 
948
###############################################################################
949
#   ToolsetSHLDLINT $name, \@args, \@objs, \@libraries )
950
#       This subroutine takes the user options and builds the rules
951
#       required to lint the program 'name'.
952
#
953
#   Arguments:
954
#       (none)
955
#
956
#   Output:
957
#       [ $(LIBDIR)/$name_lint:   .... ]
958
#           $(SHLIBLINT)
959
#
960
###############################################################################
961
 
962
sub ToolsetSHLDLINT
963
{
964
    PCLintSHLIB( @_ );
965
}
966
 
967
 
968
###############################################################################
969
#   ToolsetLD( $name, \@args, \@objs, \@libraries )
970
#       This subroutine takes the user options and builds the rules
971
#       required to link the program 'name'.
972
#
973
#   Arguments:
974
#       (none)
975
#
976
#   Output:
977
#       $(BINDIR)/name: \
978
#                       OBJS .... \
979
#                       $(BINDIR)/name.dep
980
#           $(LD)
981
#
982
#       $(BINDIR)/name.dep: $(BINDIR)
983
#       $(BINDIR)/name.dep: $(GBE_PLATFORM).mk
984
#           $(LDDEPEND)
985
#
986
#       ifeq "$(IFLAG)" "3"
987
#       -include        "$(BINDIR)/name.dep"
988
#       endif
989
#
990
#       name_ld += ...
991
#           :
992
#
993
#       name_dp += ...
994
#           :
995
#
996
###############################################################################
997
 
998
sub ToolsetLD
999
{
1000
    my ( $name, $pArgs, $pObjs, $pLibs ) = @_;
1001
    my ( $full ) = $name."$::exe";
1002
    my ( $res, @reslist );
1003
    my $no_pdb =$pdb_none;
1004
    our( $entry, $noaddlibs );
1005
 
1006
#.. Parse arguments
1007
#
1008
    foreach ( @$pArgs ) {
1009
        if (/^--Resource=(.*)/) {               # Resource definition
1010
            ($res, @reslist) = ToolsetRClist( $name, $1 );
1011
 
1012
        } elsif (/^--NoPDB$/) {
1013
            $no_pdb = 1;
1014
 
1015
        } elsif (/^--Entry=(.*)/) {
1016
            $entry = $1;
1017
 
1018
        } elsif (/^--NoAddLib/) {
1019
            $noaddlibs = 1;
1020
 
1021
        } else {
1022
            Message( "vcwin32 LD: unknown option $_ -- ignored\n" );
1023
 
1024
        }
1025
    }
1026
 
1027
#.. Cleanup rules
1028
#
1029
#   dep     Dependency file
1030
#   ld      Linker command file
1031
#   map     Map file
1032
#   pdb     Microsoft C/C++ program database
1033
#   ilk     Microsoft Linker Database
1034
#   res     Compiled resource script
1035
#
1036
    ToolsetGenerate( "\$(BINDIR)/${name}.dep" );
1037
    ToolsetGenerate( "\$(BINDIR)/${name}.ld" );
1038
    ToolsetGenerate( "\$(BINDIR)/${name}.map" );
1039
    ToolsetGenerate( "\$(BINDIR)/${name}.pdb" );
1040
    ToolsetGenerate( "\$(BINDIR)/${name}.ilk" );
1041
 
1042
#.. Linker command
1043
#
1044
    my ($io) = ToolsetPrinter::New();
1045
 
1046
    $io->Prt( "\\\n\t\t$res " ) if ( $res );
1047
    $io->Prt( "\\\n\t\t\$(BINDIR)/${name}.dep\n".
1048
              "\t\$(LD)\n\n" );
1049
 
1050
 
1051
    $io->LDDEPEND( $name );                     # standard LDDEPEND rules
1052
 
1053
#.. Linker command file
1054
#
1055
#       Now piece together a variable $(name_ld) which ends up in
1056
#       the command file linking the application.
1057
#
1058
    $io->SetTag( "${name}_ld" );                # macro tag
1059
 
1060
    $io->Label( "Linker commands", $name );     # label
1061
 
1062
    $io->Cmd( "-out:\$(subst /,\\\\,\$(BINDIR)/${full})" );
1063
    $io->Cmd( "-pdb:\$(subst /,\\\\,\$(BINDIR)/${name}).pdb" ) unless ($no_pdb);
1064
    $io->Cmd( "-debug:none" )                                  if ($no_pdb);
1065
    $io->Cmd( "-pdb:none" )                                    if ($no_pdb);
1066
    $io->Cmd( "-entry:$entry" )                                if ($entry);
1067
    $io->Cmd( "-map:\$(subst /,\\\\,\$(BINDIR)/${name}).map" );
1068
    $io->Cmd( "-nodefaultlib:LIBC" );
1069
    $io->Cmd( "-machine:IX86" );
1070
    $io->Cmd( "\$(subst /,\\\\,$res)" ) if ( $res );
1071
 
1072
    ToolsetLibStd( $pLibs )                     # push standard libraries
1073
        unless ( $noaddlibs );
1074
 
1075
                                                # object list
1076
    $io->ObjList( $name, $pObjs, \&ToolsetObjRecipe );
1077
 
1078
                                                # library list
1079
    $io->LibList( $name, $pLibs, \&ToolsetLibRecipe );
1080
 
1081
    $io->Newline();
1082
 
1083
#.. Dependencies
1084
#
1085
#       Now piece together a variable $(name_dp) which ends up in
1086
#       the command file building the application dependency list.
1087
#
1088
    $io->SetTag( "${name}_dp" );                # macro tag
1089
 
1090
    $io->DepRules( $name, $pLibs,               # library depends rules
1091
        \&ToolsetLibRecipe, "\$(BINDIR)/${full}" );
1092
 
1093
    $io->Newline();
1094
 
1095
#.. Compile up the resource file
1096
#
1097
    ToolsetRCrecipe( $res, @reslist )
1098
        if ( $res );
1099
 
1100
#.. Package up the PDB file with the program
1101
#
1102
    PackageProgAddFiles ( $name, "\$(BINDIR)/${name}.pdb", "Class=debug" ) unless ( $no_pdb );
1103
 
1104
#
1105
#   Track the name of the possible target file
1106
#   Used when creating Visual Studio projects
1107
#
1108
    $target_file_exe = "\$(BINDIR)/${full}";
1109
}
1110
 
1111
 
1112
###############################################################################
1113
#   ToolsetLD( $name, \@args, \@objs, \@libraries, \@csrc, \@cxxsrc )
1114
#       This subroutine takes the user options and builds the rules
1115
#       required to lint the program 'name'.
1116
#
1117
#   Arguments:
1118
#       (none)
1119
#
1120
#   Output:
1121
#       [ $(BINDIR)/$name_lint:   .... ]
1122
#           $(LDLINT)
1123
#
1124
###############################################################################
1125
 
1126
sub ToolsetLDLINT
1127
{
1128
    PCLintLD( @_ );
1129
}
1130
 
1131
 
1132
########################################################################
1133
#
1134
#   Push standard "system" libraries. This is a helper function
1135
#   used within this toolset.
1136
#
1137
#   Arguments:
1138
#       $plib       Reference to library array.
1139
#
1140
########################################################################
1141
 
1142
sub ToolsetLibStd
1143
{
1144
    my ($plib) = @_;
1145
 
1146
    #
1147
    #   Only add libraries if required
1148
    #
1149
    return unless( $::ScmCompilerOpts{'ADDLINKLIBS'} );
1150
 
1151
 
1152
    #
1153
    #   Appears to be a kludge that no one is happy to remove
1154
    #   If we are inluding cs or csx libraries then add some more
1155
    #
1156
    foreach (@$plib) {
1157
        if ( $_ eq 'csx$(GBE_TYPE)' || $_ eq 'cs$(GBE_TYPE)' )
1158
        {                                       # .. core services
1159
            UniquePush( $plib, "KERNEL32" );
1160
            UniquePush( $plib, "WINUX32\$(GBE_TYPE)" );
1161
            UniquePush( $plib, "WS2_32" );
1162
            last;
1163
        }
1164
    }
1165
 
1166
    #
1167
    #   Multithreaded DLL
1168
    #
1169
    push @$plib, "--ifeq=THREADMODE:D";
1170
    push @$plib, "--ifdebug";
1171
    push @$plib, "MSVCRTD";
1172
 
1173
    push @$plib, "--ifeq=THREADMODE:D";
1174
    push @$plib, "--ifprod";
1175
    push @$plib, "MSVCRT";
1176
 
1177
    #
1178
    #   Static Multithread library
1179
    #
1180
    push @$plib, "--ifeq=THREADMODE:T";
1181
    push @$plib, "--ifdebug";
1182
    push @$plib, "LIBCMTD";
1183
 
1184
    push @$plib, "--ifeq=THREADMODE:T";
1185
    push @$plib, "--ifprod";
1186
    push @$plib, "LIBCMT";
1187
 
1188
    #
1189
    #   User library
1190
    #
1191
    push @$plib, "USER32";
1192
}
1193
 
1194
 
1195
########################################################################
1196
#
1197
#   Generate a linker object recipe.  This is a helper function used 
1198
#   within this toolset.
1199
#
1200
#   Arguments:
1201
#       $io         I/O stream
1202
#
1203
#       $target     Name of the target
1204
#
1205
#       $obj        Library specification
1206
#
1207
########################################################################
1208
 
1209
sub ToolsetObjRecipe
1210
{
1211
    my ($io, $target, $obj) = @_;
1212
 
1213
    $io->Cmd( "\$(subst /,\\\\,\$(strip $obj)).$::o" );
1214
}
1215
 
1216
 
1217
########################################################################
1218
#
1219
#   Generate a linker/depend library recipe.  This is a helper function
1220
#   used within this toolset.
1221
#
1222
#   Arguments:
1223
#       $io         I/O stream
1224
#
1225
#       $target     Name of the target
1226
#
1227
#       $lib        Library specification
1228
#
1229
#       $dp         If building a depend list, the full target name.
1230
#
1231
########################################################################
1232
 
1233
sub ToolsetLibRecipe
1234
{
1235
    my ($io, $target, $lib, $dp) = @_;
1236
 
1237
    return                                      # ignore (compat)
1238
        if ( $lib eq "rt" ||        $lib eq "thread" ||
1239
             $lib eq "pthread" ||   $lib eq "nsl" ||
1240
             $lib eq "socket" );
1241
 
1242
    if ( !defined($dp) ) {                      # linker
1243
        $io->Cmd( "\$(subst /,\\\\,\$(strip $lib)).$::a" );
1244
 
1245
    } else {                                    # depend
1246
        $io->Cmd( "$dp:\t@(vlib2,$lib,LIB)" );
1247
    }
1248
}
1249
 
1250
 
1251
########################################################################
1252
#
1253
#   Parse resource file data
1254
#   This is a helper function used within this toolset
1255
#
1256
#   Arguments   : $1  BaseName
1257
#                 $2  The users resource list
1258
#                     This is a list of comma seperated files
1259
#                     The first file is the main resource script
1260
#
1261
#   Returns     : An array of resource files with full pathnames
1262
#                 [0] = The output file
1263
#                 [1] = The input file
1264
#                 [..] = Other input files
1265
#
1266
########################################################################
1267
 
1268
sub ToolsetRClist
1269
{
1270
    my ($name, $files) = @_;
1271
    my @result;
1272
 
1273
    #
1274
    #   Generate the name of the output file
1275
    #
1276
    push @result, "\$(OBJDIR)/$name.res";
1277
 
1278
    #
1279
    #   Process each user file
1280
    #
1281
    for (split( ',', $files ))
1282
    {
1283
        #
1284
        #   Locate the file.
1285
        #   If it is a generate file so it will be in the SRCS hash
1286
        #   Other wise the use will have to use Src to locate the file
1287
        #
1288
        push @result, MakeSrcResolve($_);
1289
    }
1290
 
1291
    #
1292
    #   Return the array to the user
1293
    #
1294
    return @result;
1295
}
1296
 
1297
 
1298
########################################################################
1299
#
1300
#   Generate a resource file recipe
1301
#   This is a helper function used within this tool
1302
#
1303
#   Arguments   : $1  Output resource file
1304
#                 ..  Input resource files
1305
#
1306
########################################################################
1307
 
1308
sub ToolsetRCrecipe
1309
{
1310
    my ($out, @in) = @_;
1311
 
1312
    #
1313
    #   Cleanup
1314
    #
1315
    ToolsetGenerate( $out );
1316
 
1317
    #
1318
    #   Recipe
1319
    #
1320
    MakePrint( "\n#.. Compile Resource file: $out\n\n" );
1321
    MakePrint( "$out:\t\$(GBE_PLATFORM).mk\n" );
1322
    MakeEntry( "$out:\t", "", "\\\n\t\t", " ", @in );
1323
    MakePrint( "\n\t\$(RC)\n" );
1324
    MakePrint( "\n" );
1325
}
1326
 
1327
########################################################################
1328
#
1329
#   Generate a project from the provided project solution file
1330
#   This is aimed at .NET work
1331
#
1332
#   Arguments   : $name             - Base name of the project
1333
#                 $solution         - Path to the solutionn file
1334
#                 $pArgs            - Project specific options
1335
#
1336
########################################################################
1337
 
1338
my $project_defines_done = 0;
1339
sub ToolsetPROJECT
1340
{
1341
    my( $name, $solution ,$pArgs ) = @_;
1342
    my $buildcmd = $toolset_info->{'buildcmd'};
1343
    my $cleancmd = $toolset_info->{'cleancmd'};
1344
 
1345
    #
1346
    #   Process options
1347
    #
1348
    foreach ( @$pArgs ) {
1349
        Message( "vcw32 PROJECT: unknown option $_ -- ignored\n" );
1350
    }
1351
 
1352
    my ($io) = ToolsetPrinter::New();
1353
 
1354
    #
1355
    #   Setup toolset pecific difinitions. Once
1356
    #
1357
    unless( $project_defines_done )
1358
    {
1359
        $project_defines_done = 1;
1360
        $io->PrtLn( "ifeq \"\$(DEBUG)\" \"1\"");
1361
        $io->PrtLn( "PROJECT_CMD\t:= DEBUG");
1362
        $io->PrtLn( "else");
1363
        $io->PrtLn( "PROJECT_CMD\t:= RELEASE");
1364
        $io->PrtLn( "endif");
1365
        $io->Newline();
1366
    }
1367
 
1368
    #
1369
    #   Process the build and clean commands
1370
    #       Substitute arguments
1371
    #           =TYPE=
1372
    #           =LOG=
1373
    #           =DSW=
1374
    #
1375
    $buildcmd =~ s~=TYPE=~\$\(PROJECT_CMD)~g;
1376
    $buildcmd =~ s~=LOG=~$name\$(GBE_TYPE).log~g;
1377
    $buildcmd =~ s~=DSW=~$solution~g;
1378
 
1379
    $cleancmd =~ s~=TYPE=~\$\(PROJECT_CMD)~g;
1380
    $cleancmd =~ s~=LOG=~$name\$(GBE_TYPE).log~g;
1381
    $cleancmd =~ s~=DSW=~$solution~g;
1382
 
1383
    #
1384
    #   Generate the recipe to create the project
1385
    #   Use the set_WIN32.sh file to extend the DLL search path
1386
    #
1387
    $io->Label( "Build project", $name );
1388
    $io->PrtLn( "Project_$name: $solution \$(INTERFACEDIR)/set_$::ScmPlatform.sh" );
1389
 
1390
    $io->PrtLn( "\t\$(XX_PRE)( \$(rm) -f $name\$(GBE_TYPE).log; \\" );
1391
    $io->PrtLn( "\t. \$(INTERFACEDIR)/set_$::ScmPlatform.sh; \\" );
1392
    $io->PrtLn( "\t$buildcmd; \\" );
1393
    $io->PrtLn( "\tret=\$\$?; \\" );
1394
    $io->PrtLn( "\t\$(GBE_BIN)/cat $name\$(GBE_TYPE).log; \\" );
1395
    $io->PrtLn( "\texit \$\$ret )" );
1396
    $io->Newline();
1397
 
1398
    #
1399
    #   Generate the recipe to clean the project
1400
    #
1401
    $io->Label( "Clean project", $name );
1402
    $io->PrtLn( "ProjectClean_$name: $solution" );
1403
    $io->PrtLn( "\t-\$(XX_PRE)$cleancmd" );
1404
    $io->PrtLn( "\t-\$(XX_PRE)\$(rm) -f $name\$(GBE_TYPE).log" );
1405
    $io->Newline();
1406
 
1407
}
1408
 
1409
 
1410
#.. Successful termination
1411
1;
1412