Subversion Repositories DevTools

Rev

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