Subversion Repositories DevTools

Rev

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