Subversion Repositories DevTools

Rev

Rev 7018 | Details | Compare with Previous | Last modification | View Log | RSS feed

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