Subversion Repositories DevTools

Rev

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