Subversion Repositories DevTools

Rev

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