Subversion Repositories DevTools

Rev

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