Subversion Repositories DevTools

Rev

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