Subversion Repositories DevTools

Rev

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