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