Subversion Repositories DevTools

Rev

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

Rev Author Line No. Line
363 dpurdie 1
########################################################################
6177 dpurdie 2
# COPYRIGHT - VIX IP PTY LTD ("VIX"). ALL RIGHTS RESERVED.
227 dpurdie 3
#
4
# Module name   : buildlib.pl
5
# Module type   : Makefile system
363 dpurdie 6
# Compiler(s)   : Perl
7
# Environment(s): jats
227 dpurdie 8
#
363 dpurdie 9
# Description   : Process build.pl file and create the build environment
227 dpurdie 10
#
363 dpurdie 11
# Usage         : Refer to documentation at the end of the file
227 dpurdie 12
#
363 dpurdie 13
#......................................................................#
227 dpurdie 14
 
15
use strict;
16
use warnings;
17
 
363 dpurdie 18
use JatsError;
227 dpurdie 19
use BuildVersion;
20
use BuildName;
21
use PackageEntry;
22
use JatsEnv;
23
use JatsSystem;
24
use JatsVersionUtils;
25
use FileUtils;
6133 dpurdie 26
use ToolsetFiles;
227 dpurdie 27
use Pod::Usage;
261 dpurdie 28
use Getopt::Long;
305 dpurdie 29
use File::Path;
5969 dpurdie 30
use XML::Writer;
5986 dpurdie 31
use ArrayHashUtils;
6276 dpurdie 32
use Storable qw(dclone);
227 dpurdie 33
 
34
our $BuildVersion           = "2.1.0";
35
 
36
#.. Switchs
37
#
38
our $ScmBuildlib            = 0;
39
our $ScmBuildSrc            = "";
40
 
41
our $CmdSwitch              = "";
42
our $Clobber                = 0;
43
our $Archive                = 0;
44
our $Interface              = 0;
45
our $RootOnly               = 0;
7296 dpurdie 46
our $BuildInfo              = 0;
47
our $BuildInfoFile          = 'BuildInfo.properties';
227 dpurdie 48
our $Expert                 = 0;
49
our $All                    = 0;
5109 dpurdie 50
our $Cache                  = $ENV{GBE_DPKG_CACHE_CTL} || 0;
261 dpurdie 51
our $NoPackageError         = 0;
227 dpurdie 52
our $ForceBuildPkg          = 0;
53
our $Srcdir                 = "";               # default source root
331 dpurdie 54
our $ForceBuild             = 1;
2078 dpurdie 55
our $IgnorePkgs             = 0;
4778 dpurdie 56
our $GenericBuild           = undef;            # Build System Generic Build Test
227 dpurdie 57
 
58
#.. Public symbols, referenced by many build.pl implementations
59
#
60
our $BUILDPREVIOUSVERSION   = "0.0.0";          # BuildPreviousVersion()
61
our @BUILDPLATFORMS         = ();               # BuildPlatforms()
62
our %BUILDINFO              = ();               # BuildInfo
63
our @DEFBUILDPLATFORMS      = ();
64
our %BUILDPLATFORMARGS      = ();
65
our @BUILD_ACTIVEPLATFORMS  = ();
66
our @BUILDSUBDIRS           = ();               # BuildSubDir()
67
our @BUILDSETENV            = ();               # BuildSetenv()
68
our $BUILDINTERFACE         = "";               # BuildInterface()
69
our $BUILDLOCAL             = "";               # BuildInterface()
70
our $BUILDDIRTREE           = "";               # BuildDirTree()
241 dpurdie 71
our @BUILD_BADNAME          = ();               # Unknown platforms
6276 dpurdie 72
our @GENERIC_TARGETS        = ();               # Generic targets - only one allowed
227 dpurdie 73
 
74
our $BUILDNAME              = "";               # BuildName()
75
our $BUILDVERSION           = "";               # BuildName()
6511 dpurdie 76
our $BUILDBASEVERSION       = "";               # BuildName
227 dpurdie 77
our $BUILDNAME_PACKAGE;                         # Name
78
our $BUILDNAME_VERSION;                         # Version
79
our $BUILDNAME_PROJECT;                         # Project(optional)
359 dpurdie 80
our $BUILDNAME_SUFFIX;                          # Project (available)
227 dpurdie 81
our $DEPLOY_PATCH           = 0;                # Deplyment patch number
82
 
83
our %BUILDALIAS_DELAY       = ();               # Delayed aliases
84
our %BUILDALIAS_TARGETS     = ();               # BuildAlias from --Targets
85
our %BUILDALIAS             = ();               # BuildAlias
86
our %BUILDPRODUCT           = ();               # BuildProduct
87
our %BUILDPRODUCT_PARTS     = ();               # BuildProduct parts
88
our %PKGRULES               = ();               # Package include and link rules
89
our @BUILDTOOLS             = ();               # Extended tool path
90
our $BUILDPHASE             = 0;                # In Build Phase
91
our @CLOBBERDIRS            = ();               # Directories to clobber
375 dpurdie 92
our @REMOVEDIRS             = ();               # Directories to remove - if empty
247 dpurdie 93
our %BUILD_KNOWNFILES       = ();               # Files that will be known
5679 dpurdie 94
our @BUILDEXCLUDE           = ();               # Platforms to be excluded
6684 dpurdie 95
our @BUILDARGUMENTS         = ();               # Build Arguments
96
our @LINKPKGEXLUDES         = ();               # LinkPkgExclude arguments
227 dpurdie 97
 
333 dpurdie 98
our $Makelib                = "";
263 dpurdie 99
our $GBE_CORE;                                  # Root of JATS
100
our $InterfaceVersion;                          # Interface directory format version
3967 dpurdie 101
our $ScmRoot;                                   # Package Root
263 dpurdie 102
our $ScmInterface;                              # Interface directory
363 dpurdie 103
our $ScmBuildFilter;                            # Build Filter when build was created
4003 dpurdie 104
our $NoBuild                = 0;                # Dummy Build under ABT only
6177 dpurdie 105
our $BUILD_UUID             = time() . substr(rand(),2); # Build Unique Identifier
227 dpurdie 106
 
107
my  $DeleteDPACKAGE         = 0;                # Must clobber DPACKAGE
305 dpurdie 108
my  $build_source_pkg       = 0;                # Flag to build source package
227 dpurdie 109
my  $opt_help               = 0;
6619 dpurdie 110
my  $opt_localCache         = 0;                # Create cache within the interface directory
359 dpurdie 111
my  $sandbox_exact          = 0;                # Exact or in-exact sandbox
6133 dpurdie 112
my  $pkgFromSandbox         = 0;                # Flags that we have imported a package from a sandbox
227 dpurdie 113
 
7296 dpurdie 114
my  $toolsetData;                               # Parsed toolset data
6133 dpurdie 115
my  $genToolsetPlatform     = 0;                # BuildToolset directive has been seen
116
my  $genToolsetActive       = 0;                # TOOLSET platform required:1, Error:2
117
my  $toolsetPlatform        = 'NONE';           # TOOLSET Display Value
118
my  @genToolsetArgs;                            # Args for a generated TOOLSET
6276 dpurdie 119
my  $descpkgPath;                               # Path to the dscpkg file
6133 dpurdie 120
 
227 dpurdie 121
BuildLibInit();
122
 
123
sub BuildLibInit
124
{
125
 
126
#.. Set environment
127
#
331 dpurdie 128
    EnvImport( 'GBE_VERSION' );
129
    EnvImport( 'GBE_BIN' );
130
    EnvImport( 'GBE_CORE' );
131
    EnvImport( 'GBE_PERL' );
132
    EnvImport( 'GBE_TOOLS' );
133
    EnvImport( 'GBE_CONFIG' );
134
    EnvImport( 'GBE_DPKG' );
135
    EnvImport( 'GBE_MACHTYPE' );
136
    EnvImport( 'USER' );
137
    EnvImport( 'GBE_HOSTNAME');
7296 dpurdie 138
    EnvImport( 'GBE_DRV' ) if ( $ScmHost ne 'Unix' );   # DOS or WIN special
227 dpurdie 139
 
6276 dpurdie 140
    EnvImportOptional ( 'GBE_DPKG_ESCROW','' );
4688 dpurdie 141
    EnvImportOptional ( 'GBE_DPKG_REPLICA','' );
227 dpurdie 142
    EnvImportOptional ( 'GBE_DPKG_STORE','' );
143
    EnvImportOptional ( 'GBE_DPKG_CACHE','' );
144
    EnvImportOptional ( 'GBE_DPKG_LOCAL','' );
145
    EnvImportOptional ( 'GBE_DPKG_SBOX' ,'' );
313 dpurdie 146
    EnvImportOptional ( 'GBE_DPLY'      ,'' );
341 dpurdie 147
    EnvImportOptional ( 'GBE_SANDBOX'   ,'' );
227 dpurdie 148
 
7296 dpurdie 149
    EnvImportOptional ( 'GBE_PLATFORM' );               # optional PLATFORM filter
150
    EnvImportOptional ( 'GBE_BUILDFILTER' );            # optional BUILD filter       
151
    EnvImportOptional ( 'GBE_ABT' );                    # optional ABT flags          
227 dpurdie 152
 
153
#.. Common stuff
154
#
155
    require "$::GBE_TOOLS/common.pl";
331 dpurdie 156
    CommonInit( 'buildlib' );
227 dpurdie 157
    Debug( "Version:   $BuildVersion" );
279 dpurdie 158
    Require( "$::GBE_CONFIG/PLATFORM", "PLATFORM_CFG.PM"  );
227 dpurdie 159
 
160
#.. Parse command line
161
#
162
    $ScmBuildSrc = $0;                          # Name of the build file
6276 dpurdie 163
    shift @ARGV;                                # No longer used
164
    $::ScmRoot = $CwdFull;                      # $CwdFull does not have a driver letter. $CwdFull does
333 dpurdie 165
    $Makelib = shift @ARGV;                     # Only for legacy build.pl files
227 dpurdie 166
 
261 dpurdie 167
    Verbose ("Command Line: @ARGV");
313 dpurdie 168
    my $result = GetOptions( "help|h:+"      => \$opt_help,
169
                             "man:3"         => \$opt_help,
170
                             "debug:+"       => \$::ScmDebug,
171
                             "verbose:+"     => \$::ScmVerbose,
172
                             "expert:1"      => \$Expert,
173
                             "all"           => \$All,
331 dpurdie 174
                             "cache:+"       => \$Cache,
313 dpurdie 175
                             "package"       => \$NoPackageError,
2078 dpurdie 176
                             "nopackages"    => \$IgnorePkgs,
313 dpurdie 177
                             "forcebuildpkg" => \$ForceBuildPkg,
331 dpurdie 178
                             "force!"        => \$ForceBuild,
4778 dpurdie 179
                             "generic!"      => \$GenericBuild,
6619 dpurdie 180
                             "localcache!"   => \$opt_localCache,
7296 dpurdie 181
                             "buildinfo:s"   => \$BuildInfoFile,
313 dpurdie 182
                             );
261 dpurdie 183
    Usage() if ( $opt_help || !$result );
227 dpurdie 184
 
331 dpurdie 185
    Debug( "Host:          ", $ScmHost );
6276 dpurdie 186
    Debug( "Cwd:           ", $CwdFull );
187
    Debug( "ScmRoot:       ", $::ScmRoot );
333 dpurdie 188
    Debug( "Makelib:       ", $Makelib );
331 dpurdie 189
    Debug( "BuildFile:     ", $ScmBuildSrc );
190
    Debug( "Debug:         ", $::ScmDebug );
191
    Debug( "Verbose:       ", $::ScmVerbose );
192
    Debug( "Expert:        ", $Expert );
193
    Debug( "All:           ", $All );
194
    Debug( "Cache:         ", $Cache );
195
    Debug( "package:       ", $NoPackageError );
196
    Debug( "ForcePkg  :    ", $ForceBuildPkg );
197
    Debug( "ForceBuild :   ", $ForceBuild );
4778 dpurdie 198
    Debug( "IgnorePkgs :   ", $IgnorePkgs );
199
    Debug( "GenericTest :  ", $GenericBuild );
6619 dpurdie 200
    Debug( "LocalCache :   ", $opt_localCache );
227 dpurdie 201
 
202
#.. Command
203
#
3967 dpurdie 204
 
205
    $CmdSwitch = (lc shift @ARGV) if @ARGV;
331 dpurdie 206
    Debug( "CmdSwitch:     ", $CmdSwitch );
227 dpurdie 207
 
331 dpurdie 208
    if ( $CmdSwitch )
209
    {
210
        if ( $CmdSwitch eq "interface" ) {
211
            $Interface      = 1;
227 dpurdie 212
 
331 dpurdie 213
        } elsif ( $CmdSwitch eq "rootonly" ) {
214
            $RootOnly       = 1;
227 dpurdie 215
 
331 dpurdie 216
        } elsif ( $CmdSwitch eq "clobber" ) {
217
            $Clobber        = 1;
227 dpurdie 218
 
7296 dpurdie 219
        } elsif ( $CmdSwitch eq "buildinfo" ) {
220
            $BuildInfo      = 1;
221
            $Interface      = 1;
222
            unlink $BuildInfoFile;
223
 
331 dpurdie 224
        } elsif ( $CmdSwitch eq "help" || $CmdSwitch eq "usage" ) {
225
            $opt_help = 1;
226
            Usage();
227 dpurdie 227
 
331 dpurdie 228
        } else {
229
            Usage( "(E) build. Unknown command \"$CmdSwitch\"" );
230
        }
231
    }
227 dpurdie 232
 
331 dpurdie 233
    #
341 dpurdie 234
    #   If we are not performing a ForceBuild, then we don't need to continue
235
    #   We have updated the interface directory with BuildPkgArchive
236
    #   information.
331 dpurdie 237
    #
341 dpurdie 238
    unless ( $::GBE_SANDBOX )
331 dpurdie 239
    {
341 dpurdie 240
        TestForForcedBuild();
227 dpurdie 241
    }
242
 
243
    #
244
    #   Must inform makelib that its running under buildlib
245
    #
246
    $ScmBuildlib = 1;
247
 
248
    #
249
    #   In clobber mode System commands will not force termination
250
    #   otherwise, within build.pl, a failed system command will die.
251
    #
252
    SystemConfig ('UseShell' => 1,
283 dpurdie 253
                  'ExitOnError' => ($Clobber == 0) );
5109 dpurdie 254
 
255
    #
256
    #   Capture messages while processing directives
257
    # 
258
    StartCapture(1) 
259
        unless ($Clobber);
227 dpurdie 260
}
261
 
262
 
263
#-------------------------------------------------------------------------------
264
# Function        : Log
265
#
266
# Description     : Internal function to generate a log file of the build process
341 dpurdie 267
#                   The function will print its arguments to the screen and a log file
227 dpurdie 268
#
269
# Inputs          : Arguments will be printed
270
#
271
# Returns         : Nothing
272
#
273
sub Log
274
{
275
    if ( ! $Clobber )
276
    {
261 dpurdie 277
        print "@_\n";
7296 dpurdie 278
        FileAppend ('build.log', \@_ ) unless $BuildInfo;
227 dpurdie 279
    }
280
}
281
 
282
#-------------------------------------------------------------------------------
283
# Function        : BuildSubDir
284
#
285
# Description     : Specify one or more directories in which makefile.pl's can be
286
#                   found to be processed.
287
#
288
#                   This function will flag the build 'src' dir.
289
#                   This will be the first directory specified UNLESS there
290
#                   is a 'src' directory in the list
291
#
292
#                   The function may be called multiple times.
293
#
294
# Inputs          : NewDirs             - An array of directories
295
#
296
# Returns         : Nothing
297
#
298
 
299
sub BuildSubDir
300
{
301
    my( @NewDirs );
302
 
303
    @NewDirs = map { split /\s+/ } @_;
304
    @NewDirs = grep { defined $_ } @NewDirs;
305
 
306
    Debug( "BuildSubDir(@NewDirs)" );
307
 
308
    foreach my $ThisDir ( @NewDirs )
309
    {
310
        unless ( $Clobber )
311
        {
2450 dpurdie 312
            $ThisDir =~ s~/+$~~;
227 dpurdie 313
            if ( $ThisDir eq "." )
314
            {
315
                Error( "BuildSubDir() cannot specify the current directory (.)",
316
                       "The makefile.pl in the root directory is included in all makefile.pl's" );
317
            }
318
 
319
            if ( $ThisDir =~ m~\\~)
320
            {
321
                Warning ("BuildSubDir contains a '\\' character: $ThisDir" );
322
            }
323
            if ( grep /^$ThisDir$/, @BUILDSUBDIRS )
324
            {
325
                Warning( "BuildSubDir() duplicate subdirectory ignored '$ThisDir'." );
326
                next;
327
            }
328
            if ( ! ( -e $ThisDir and -d $ThisDir ) )
329
            {
330
                Error( "BuildSubDir() non-existent subdirectory: '$ThisDir'." );
331
            }
332
            if ( ! -f $ThisDir . '/makefile.pl' )
333
            {
334
                Error( "BuildSubDir() makefile.pl not found in subdirectory: '$ThisDir'." );
335
            }
336
 
337
            push( @BUILDSUBDIRS, $ThisDir );
338
        }
339
 
340
        #
341
        #   Capture the first source directory mentioned
342
        #   This will be used as the root of the build
343
        #
344
        #   If there is a Src directory then use this
345
        #
346
        $Srcdir = $ThisDir
347
            if ( $ThisDir =~ m/^src$/i );
348
        $Srcdir = $ThisDir
349
            unless ( $Srcdir );
350
    }
351
}
352
 
353
#-------------------------------------------------------------------------------
6133 dpurdie 354
# Function        : isKeyword 
355
#
356
# Description     : Test for an attempt to use reserved platform name 
357
#
358
# Inputs          : $test   - Name to test
359
#
360
# Returns         : Reserved word or none
361
#
362
sub isKeyword
363
{
364
    my ($test) = @_;
6198 dpurdie 365
    foreach my $keyword ( @PlatformConfig::BuildKeywords )
6133 dpurdie 366
    {
367
        return $keyword if (uc($test) eq $keyword);
368
    }
369
 
370
    return undef;
371
}
372
 
373
 
374
#-------------------------------------------------------------------------------
227 dpurdie 375
# Function        : BuildAlias
376
#
377
# Description     : Create an alias for multiple targets
378
#                   The default operations will:
379
#                       Add the alias as a default platform (* in the makefile.pl)
380
#                       Perform an implicit BuildPlatform for the alias targets
381
#
382
#                   In hindsight this was not good. Options modify the behaviour
383
#                   Options:
384
#                       --NotDefault    The alias will not be a part of the default
385
#                                       platform for the makefile.pls
386
#                       --Define        Simply define text substitution
387
#                                       Do not implicitly create platforms
388
#                       --Target        Accumulate platforms with specified targets
389
#                                       Complete alias determination is delayed
390
#                                       The named targets are specified as an alias
391
#                                       until the calculation is done
392
#
393
# Inputs          : alias[,--options]   comma seperated options
394
#                   arguments           alias arguments; platforms or targets
395
#
396
# Returns         : Nothing
397
#
398
sub BuildAlias
399
{
400
    my( $alias, @arguments ) = @_;
401
    my $notdefault;
402
    my $define;
403
    my $target_mode;
404
 
405
    Debug( "BuildAlias($alias, @arguments)" );
406
    Error ("BuildAlias: No platforms specified") unless ( @arguments );
407
    Error( "BuildAlias() must appear before BuildName()..." ) if ( $BUILDNAME );
408
 
409
    #   Parse attributes
410
    #
411
    my ( @attrs ) = split( ',', $alias );
412
 
413
    $alias = "";
414
    foreach ( @attrs ) {
415
        if ( /^--/ ) {
416
            if ( /^--NotDefault$/ ) {
417
                $notdefault = 1;
418
 
419
            } elsif ( /^--Define$/ ) {
420
                $define = 1;
421
 
422
            } elsif ( /^--Target$/ ) {
423
                $target_mode = 1;
424
 
425
            } else {
426
                Warning( "BuildAlias() unknown attribute: $_ -- ignored" );
427
            }
428
 
429
        } else {
5262 dpurdie 430
            Error( "BuildAlias() multiple alias specifications", "First: $alias and now $_" )
227 dpurdie 431
                if ( $alias ne "" );
432
            $alias = $_;
433
        }
434
    }
435
    Error( "BuildAlias() missing alias specifications" )
436
        if ( $alias eq "" );
437
 
6198 dpurdie 438
    if ( isKeyword($alias) ) {
7447 dpurdie 439
        abtWarning(1, "BuildAlias() attempt to alias a keyword: $alias");
6198 dpurdie 440
    }
227 dpurdie 441
 
442
    #
443
    #   If we need to recalculate the alias based on targets, then tag the alias
444
    #   to be processed
445
    #
446
    $BUILDALIAS_TARGETS{ $alias } = ''
447
        if ( $target_mode );
448
 
449
    #   Define alias
450
    #
6133 dpurdie 451
    if ( PlatformConfig::targetHasTag($alias, 'GENERIC') )
227 dpurdie 452
    {
4551 dpurdie 453
        Error( "BuildAlias() cannot create an alias named $alias", "That name is reserved for generic targets" );
227 dpurdie 454
    }
455
    elsif ( $alias ne quotemeta( $alias ) )
456
    {
7447 dpurdie 457
        abtWarning (1, "BuildAlias() alias '$alias' contains invalid characters");
227 dpurdie 458
    }
459
    elsif ( $BUILDALIAS{ $alias } )
460
    {
7447 dpurdie 461
        abtWarning   (1, "BuildAlias() duplicate alias '$alias'")
227 dpurdie 462
    }
463
    else
464
    {
465
        #
466
        #   Expand alias UNLESS using --Target.
467
        #   The --Target is a real target and not a subject to alias expansion
468
        #   This solves order dependancy problems.
469
        #
470
        @arguments = ExpandPlatforms( @arguments )
471
            unless $target_mode;
472
 
6133 dpurdie 473
        my $platform = '';                   # current platform
227 dpurdie 474
        my @pargs = ();                      # current args
475
 
476
        #
477
        #   Process the expanded arguments
478
        #   Collect arguments and process when a new platform is discovered
479
        #
480
        foreach my $arg ( @arguments, '++' )
481
        {
482
            if ( $arg =~ /^--/ )
483
            {
484
                push @pargs, $arg;
485
                next;
486
            }
487
            else
488
            {
489
                #
490
                #   Start of a platform
491
                #   Process previous data, once a platform has been seen
492
                #
493
                if ( $platform )
494
                {
495
                    #   Add arguments to BUILDALIAS as we see them
496
                    #
497
                    HashJoin( \%BUILDALIAS, ' ', $alias, $platform );
498
                    HashJoin( \%BUILDALIAS, ' ', $alias, grep(!/^--Uses=/, @pargs) );
499
 
500
                    #
501
                    #   The BuildAlias can also define a platform.
502
                    #   (Sounded like a good idea at the time!)
503
                    #
504
                    unless ( $define || $target_mode )
505
                    {
506
                        push @pargs, '--NotDefault' if ( $notdefault );
507
                        push @pargs, '--FunctionName=BuildAlias';
508
                        BuildPlatforms( $platform, @pargs );
509
                    }
6276 dpurdie 510
                    else
511
                    {
512
                        my @badArgs = grep (/^--/, @pargs) ;
513
                        if (@badArgs) {
514
                            Warning("Platform arguments in define mode are ignored:($platform)", @badArgs);
515
                        }
516
 
517
                    }
227 dpurdie 518
                }
519
 
520
                #
521
                #   Start collecting args for the next platform
522
                #
523
                @pargs = ();
524
                $platform = $arg;
525
            }
526
        }
527
    }
528
}
529
 
6133 dpurdie 530
#-------------------------------------------------------------------------------
531
# Function        : BuildAliasDef  
532
#
533
# Description     : Shorthand for BuildAlias (xxx,-Define, ... )
534
#                   The way is should have been done  :(
535
#
536
# Inputs          : $alias          Name of alias to define
537
#                   arguments       Alias arguments; platforms or targets
538
#
539
sub BuildAliasDef()
540
{
541
    my( $alias, @arguments ) = @_;
542
    BuildAlias($alias . ',--Define', @arguments);
543
}
227 dpurdie 544
 
545
#-------------------------------------------------------------------------------
546
# Function        : Process_TargetAlias
547
#
548
# Description     : Post Process the --Target option for the build alias
549
#                   Filter all platforms and extract those with a matching targets
550
#
551
# Inputs          : None
552
#
553
# Returns         : Nothing
554
#
555
sub Process_TargetAlias
556
{
557
    #
558
    #   Merge any delayed aliases with the complete set of alias
559
    #   Delayed alias are not used in expansions during the processing
5410 dpurdie 560
    #   of platforms and targets, but can be used to pick up errors
227 dpurdie 561
    #
562
    while ( my($key,$value) = each(%BUILDALIAS_DELAY) )
563
    {
564
        if ( exists($BUILDALIAS{$key}) )
565
        {
5867 dpurdie 566
            abtWarning(0,"BuildAlias() duplicates internal alias '$key'");
227 dpurdie 567
            next;
568
        }
569
        $BUILDALIAS{$key} = $value;
570
    }
5410 dpurdie 571
    ErrorDoExit();
227 dpurdie 572
 
6276 dpurdie 573
    #
574
    #   Empty so that its not seen in Buildfile.
575
    #
576
    %BUILDALIAS_DELAY =();
577
 
227 dpurdie 578
    foreach my $alias ( keys %BUILDALIAS_TARGETS )
579
    {
580
        Debug( "BuildTargetAlias($alias)" );
581
 
582
        #
583
        #   Replace the existing alias - it has done its JOB
584
        #
585
        my $arguments = delete $BUILDALIAS{ $alias } ;
586
 
587
        foreach my $arg ( split / /, $arguments )
588
        {
589
            if ( $arg =~ /^--/ )                # argument
590
            {
591
                #   Add arguments to BUILDALIAS as we see them
592
                #
593
                HashJoin( \%BUILDALIAS, ' ', $alias, $arg );
594
                next;
595
            }
596
 
597
            foreach my $platform ( keys %BUILDINFO )
598
            {
599
                foreach my $element ( qw (TARGET BASE ) )
600
                {
601
                    my $target = $BUILDINFO{$platform}{$element};
602
                    if ( $target && $target eq $arg )
603
                    {
604
                        HashUniqueJoin( \%BUILDALIAS, ' ', $alias, $platform );
605
                        Debug( "BuildTargetAlias: $alias, $target -> $platform" );
606
                    }
607
                }
608
            }
609
        }
610
    }
611
}
612
 
613
#-------------------------------------------------------------------------------
6133 dpurdie 614
# Function        : CleanUp_Aliases 
615
#
616
# Description     : Will fully expand aliases to simplify display and processing 
617
#                       Remove arguments that  start with a '-'
618
#                       Remove bits that start with a !
619
#
620
# Inputs          : 
621
#
622
# Returns         : 
623
#
624
sub CleanUp_Aliases
625
{
626
    #
627
    #   Clean up Aliases
628
    #
629
#DebugDumpData("BEFORE CleanUp_Aliases", \%BUILDALIAS);
6276 dpurdie 630
 
6133 dpurdie 631
    foreach my $alias ( keys %BUILDALIAS )
632
    {
6276 dpurdie 633
        #
634
        #   Build hash of bits to be added and bits to be removed
635
        #   Remove all options - only need platforms
636
        #
6133 dpurdie 637
        my @aliasList = split(/ /, $BUILDALIAS{$alias});
638
        my @expanded =  ExpandPlatforms(@aliasList);
639
 
640
        my %add;
641
        my %remove;
642
 
643
        foreach ( @expanded)
644
        {
645
            if (m/^-/) {
646
            } elsif (m/^!(.*)/) {
647
                $remove{$1} = 1;
648
            } else {
649
                $add{$_} = 1;
650
            }
651
        }
652
 
653
        #
654
        #   If there are NO additive expressions in the alias, then
655
        #   assume all the active targets
656
        #
657
        unless (keys %add) {
6276 dpurdie 658
            %add = map { $_ => 1 } @BUILD_ACTIVEPLATFORMS;
6133 dpurdie 659
        }
660
 
661
        foreach ( keys %remove) {
662
            delete $add { $_};
663
        }
664
 
6276 dpurdie 665
        #
666
        #   Delete ALIAS if it has no expansion
667
        #       May cause issues with the Platforms directive
668
        #
669
        if (keys %add) {
670
            $BUILDALIAS{$alias} = join(' ',keys %add);
671
        } else {
672
            delete $BUILDALIAS{$alias};
673
        }
6133 dpurdie 674
    }
675
#DebugDumpData("AFTER CleanUp_Aliases", \%BUILDALIAS);
676
}
677
 
6276 dpurdie 678
#-------------------------------------------------------------------------------
679
# Function        : ProcessBuildExclude  
680
#
681
# Description     : Process BuildExclude directive info
682
#                   A list of targets to be excluded
683
#                   INSTRUMENT is a key word
684
#  
685
#
686
# Inputs          : None
687
#
688
# Returns         : Modifies BUILDINFO
689
#
690
sub ProcessBuildExclude
691
{
692
    for my $word (@BUILDEXCLUDE)
693
    {
694
        Debug("ProcessBuildExclude: $word");
695
        Error('BuildExclude: Unknown option: ' . $word) if ($word =~ m~^-~);
696
        Error('BuildExclude: Invalid format: ' . $word) if ($word =~ m~^!~);
6133 dpurdie 697
 
6276 dpurdie 698
        #
699
        #   INSTRUMENT is a key word
700
        #       Remove all instrumented builds
701
        #
702
        if ($word eq 'INSTRUMENT')
703
        {
704
            foreach my $platform ( keys %BUILDINFO )
705
            {
706
                if ( PlatformConfig::targetHasTag( $platform, 'INSTRUMENT') ) {
707
                    $BUILDINFO{$platform}{NOT_AVAILABLE} = 2;
708
                    Debug("ProcessBuildExclude. Remove $platform ");
709
                }
710
            }
711
        }
712
        elsif (exists $BUILDINFO{$word} )
713
        {
714
            $BUILDINFO{$word}{NOT_AVAILABLE} = 2;
715
            Debug("ProcessBuildExclude. Remove $word ");
716
 
717
        } else {
718
            abtWarning(0,'BuildExclude: Unknown target:' . $word ) 
719
        }
720
    }
721
    ErrorDoExit();
722
}
723
 
6133 dpurdie 724
#-------------------------------------------------------------------------------
227 dpurdie 725
# Function        : BuildProduct
726
#
727
# Description     : Create a family of Platforms with a common product line
728
#                   ie: Create two flavors of the TP5, one based on the MOSF and
729
#                   the othe based on the MOS68 toolset.
730
#
731
# Inputs          : $product[,opts]+    The name of the product
732
#                                       This will be the base name for the family
733
#                                       Allowed options are:
6192 dpurdie 734
#                                           --NotDefault       : This is not a default build platform
735
#                                           --Uses=x1,x2:x3    : All use another platform
736
#                                           --Alias=y1,y2:x3   : All alias to this name
227 dpurdie 737
#
738
#                   platforms           One or more root platforms, with options
739
#                                       The platform is macro expanded.
740
#                                       Options may be a part of the platform or
741
#                                       distinct.
742
#
743
# Returns         :
744
#
745
 
746
sub BuildProduct
747
{
748
    my( $product, @arguments ) = @_;
749
    my $notdefault = 0;
6192 dpurdie 750
    my @commonArgs = ();
227 dpurdie 751
 
752
    Debug( "BuildProduct($product, @arguments)" );
753
    Error( "BuildProduct must appear before BuildName()..." )
754
        if ( $BUILDNAME ne "" );
755
 
756
    #   Parse attributes
757
    #
758
    my( @attrs ) = split( ',', $product );
759
 
760
    $product = "";
761
    foreach ( @attrs ) {
762
        if ( /^--/ ) {
763
            if ( /^--NotDefault$/ ) {
764
                $notdefault++;
765
 
6192 dpurdie 766
            } elsif ( /^(--Uses=.*)/ ) {
767
                UniquePush (\@commonArgs, $1 );
227 dpurdie 768
 
5115 dpurdie 769
            } elsif ( /^(--Alias=.*)/ ) {
6192 dpurdie 770
                UniquePush (\@commonArgs, $1 );
5115 dpurdie 771
 
227 dpurdie 772
            } else {
773
                Warning( "BuildProduct() unknown attribute: $_ -- ignored" );
774
            }
775
 
776
        } else {
777
            Error( "BuildProduct() multiple product specifications not allowed" )
778
                if ( $product ne "" );
779
            $product = $_;
780
        }
781
    }
782
 
783
    #
784
    #   Sanity test
785
    #
786
    Error( "BuildProduct() missing product specifications" )
787
        if ( $product eq "" );
788
 
789
    Error( "BuildProduct() product '$product' contains invalid characters" )
790
        if ( $product ne quotemeta( $product ) );
791
 
792
    Error( "BuildProduct() duplicate product '$product'" )
793
        if ( $BUILDPRODUCT{ $product } );
794
 
795
    Error( "BuildProduct() duplicate alias '$product'" )
796
        if ( $BUILDALIAS{ $product } );
797
 
798
    #
799
    #   Expand the user specified targets to allow the use of BuildAlias
800
    #   The (bad) side effect of this is that target options get reorganised
801
    #       PLATFORM,--Uses=ANOTHER  ==> PLATFORM --Uses=ANOTHER
802
    #
6192 dpurdie 803
    #   Insert markers(++) into @arguments to mark when to process collected data
227 dpurdie 804
    #   Insert before each PLATFORM and at the end of the list
805
    #   platform specifier or the end of the list. Scan the arguments
806
    #
807
    @arguments = ExpandPlatforms( @arguments );
808
    my @new_args;
809
    foreach  ( @arguments )
810
    {
811
        push (@new_args, '++') unless ( m/^--/ );
812
        push (@new_args, $_ );
813
    }
814
    push (@new_args, '++');
815
    shift @new_args if $new_args[0] eq '++';
816
 
6192 dpurdie 817
    my @targs = @commonArgs;
227 dpurdie 818
    my $target;
819
    foreach my $arg ( @new_args )
820
    {
821
        #
822
        #   Collect per-platform arguments
823
        #
6192 dpurdie 824
        if ( $arg =~ /^--/ ) {
227 dpurdie 825
            push @targs, $arg;
826
            next;
827
        }
828
 
829
        #
830
        #   Collect target(platform) name
831
        #
832
        unless ( $arg eq '++' )
833
        {
834
            $target = $arg;
835
            Error( "BuildProduct() cannot create a product based on a GENERIC platform" )
6133 dpurdie 836
                if ( PlatformConfig::targetHasTag($target,'GENERIC') );
227 dpurdie 837
            next;
838
        }
839
 
840
        #
841
        #   Infer a BuildPlatform
842
        #   Do not provide a platform name. This will be created later when the
843
        #   full name is known - or can be calculated.
844
        #
6192 dpurdie 845
        CreateBuildPlatformEntry('BuildProduct', $notdefault, $product, $target, \@targs );
227 dpurdie 846
 
6192 dpurdie 847
        @targs = @commonArgs;
227 dpurdie 848
        $target = undef;
849
    }
850
}
851
 
852
#-------------------------------------------------------------------------------
853
# Function        : CreateBuildPlatformEntry
854
#
855
# Description     : Internal routine to create the Build Entry
856
#                   Single point to create a platform, whatever one of those is
857
#
858
# Inputs          : $fname                  - Name of invoking directive
859
#                   $notdefault             - True if the platform is not to be added to the
860
#                                             list of default platforms
861
#                   $product                - Optional product name
862
#                   $target                 - Target platform name
863
#                   $pArgs                  - Ref to an array of platform arguments
6192 dpurdie 864
#                                             Known: --Uses=aaa,bbb and --Alias=xxx,yyy
227 dpurdie 865
#
866
# Returns         :
867
#
868
 
869
sub CreateBuildPlatformEntry
870
{
6192 dpurdie 871
    my ($fname, $notdefault, $product, $target, $pArgs ) = @_;
227 dpurdie 872
    my %buildentry;
873
    my $platform;
874
 
875
    #
876
    #   Create a basic BUILDINFO entry
877
    #
878
    $buildentry{FNAME} = $fname;
6276 dpurdie 879
    $buildentry{NOT_DEFAULT} = $notdefault if $notdefault;
227 dpurdie 880
    $buildentry{PRODUCT} = $product;
881
    $buildentry{TARGET} = $target;
882
    $buildentry{BASE} = $target;
363 dpurdie 883
    foreach ( @$pArgs )
884
    {
885
        if ( m~^--Alias=(.+)~ ) {
6192 dpurdie 886
            foreach my $alias (split('[:,]',$1))
6133 dpurdie 887
            {
888
                Error ("$fname() attempt to alias a keyword: $alias")
889
                    if ( isKeyword($alias) );
890
                push @{$buildentry{USERALIAS}},$alias;
891
            }
6192 dpurdie 892
        } elsif ( m~^--Uses=(.+)~ ) {
893
            push @{$buildentry{USES}},split('[:,]',$1);
894
 
6133 dpurdie 895
        } else {
363 dpurdie 896
            push @{$buildentry{ARGS}}, $_;
897
        }
898
    }
227 dpurdie 899
 
4728 dpurdie 900
    #   Detect reserved words being misused as a platform name
6133 dpurdie 901
    #   At the moment, the value of NATIVE and TOOLSET are calculate towards the end of the
902
    #   build process so that it can be limited to platforms that are present.
903
    foreach my $reserved ( qw (NATIVE TOOLSET INSTRUMENT))
904
    {
905
        Error("Invalid use of the platform alias $reserved","The $reserved alias cannot be used to define build platforms")
906
            if (uc($target) eq uc($reserved));
907
    }
4728 dpurdie 908
 
227 dpurdie 909
    #
6276 dpurdie 910
    #   Expand families of platforms into multiple platforms
911
    #       ie: DEVLINUX -> COBRA, VIPER, ....
227 dpurdie 912
    #
6276 dpurdie 913
    foreach my $name (@PlatformConfig::BuildFamilies)
227 dpurdie 914
    {
297 dpurdie 915
        #
6276 dpurdie 916
        #   Is this target a buildFamily alias
303 dpurdie 917
        #
6276 dpurdie 918
        if (uc($target) eq uc($name))
919
        {
920
            #
921
            #   Get the list of targets that have been tagged with the family name
922
            #   Must exist - else its an internal error
923
            #   
924
            my @targets = PlatformConfig::getTargetsByTag($name);
925
            Error ("Internal: No platforms are tagged as members of $name") unless @targets;
303 dpurdie 926
 
6276 dpurdie 927
            #   Instantiate all targets
928
            #       Give them an ALIAS for the Family name
929
            #       Register new enrty with the build system
930
            #
931
            foreach my $target ( @targets )
932
            {
933
                my $pInfo = dclone(\%buildentry);
934
                $pInfo->{ALIAS} = $pInfo->{TARGET};
935
                $pInfo->{TARGET} = $target;
936
                AddBuildPlatformEntry( $pInfo );
937
            }
938
            #   Mark the original entry as a TEMPLATE so that it won't be added
939
            $buildentry{TEMPLATE} = 1;
940
            last;
227 dpurdie 941
        }
942
    }
6276 dpurdie 943
 
227 dpurdie 944
    #
6276 dpurdie 945
    #   Add the basic entry into the build system, unless its been flagged as a TEMPLATE
227 dpurdie 946
    #
947
    AddBuildPlatformEntry (\%buildentry )
948
        unless ( $buildentry{TEMPLATE} );
949
}
950
 
951
#-------------------------------------------------------------------------------
952
# Function        : AddBuildPlatformEntry
953
#
954
# Description     : Internal routine to add a Build Entry into the build system
955
#                   This function MAY be called from the build extensions
956
#
957
#                   NOTES:
958
#                   No processing of the info structure is performed. This MUST
959
#                   have been done before now.
960
#
961
#                   Additional information may be added to the structure.
962
#
963
#
964
# Inputs          : $pInfo              - Reference to a BuildInfo structure
965
#
966
# Returns         : Nothing
967
#
968
sub AddBuildPlatformEntry
969
{
970
    my ($pInfo) = @_;
971
    my $fname = $pInfo->{FNAME};
972
 
973
    #
6276 dpurdie 974
    #   Ensure that it exsists and is numeric
975
    #
976
    $pInfo->{NOT_AVAILABLE} = 0;
977
 
978
    #
227 dpurdie 979
    #   Locate the optional PLATFORM configuration file
980
    #   If it does exist then it can extend build-time information
981
    #
982
    my $target = $pInfo->{TARGET};
241 dpurdie 983
 
279 dpurdie 984
    #
4551 dpurdie 985
    #   Detect GENERIC targets
986
    #       The Build file is only allowed to have one that can be built on any one machine
987
    #
6276 dpurdie 988
    my $buildAvailability = PlatformConfig::targetHasTag( $target, 'MACHTYPE' );
989
    if (PlatformConfig::targetHasTag( $target, 'GENERIC' ) )
4551 dpurdie 990
    {
991
        UniquePush (\@GENERIC_TARGETS, $target );
6133 dpurdie 992
    }
993
 
994
    #
995
    #   Detect GENERIC_<machType> targets
996
    #
6276 dpurdie 997
    if (PlatformConfig::targetHasTag( $target, 'GENERIC_MACHTYPE' ) )
6133 dpurdie 998
    {
4551 dpurdie 999
        $pInfo->{IS_GENERIC} = 1;
6133 dpurdie 1000
        $pInfo->{ALIAS} = 'GENERIC';
1001
        $pInfo->{NOT_AVAILABLE} = 1 unless needToolset();
4551 dpurdie 1002
    }
1003
 
1004
    #
279 dpurdie 1005
    #   Ensure target is known to JATS
6276 dpurdie 1006
    #   Remove unknown targets from the build. 
1007
    #   Create a list of unknown targets and report them later.
279 dpurdie 1008
    #
6276 dpurdie 1009
    unless ( $pInfo->{NOT_AVAILABLE} || exists $BUILDINFO{$target} || $pInfo->{IS_GENERIC}  )
227 dpurdie 1010
    {
6276 dpurdie 1011
        my $base_target = PlatformConfig::targetHasTag( $target, 'BASE_TARGET' ) || $target;
279 dpurdie 1012
        unless ( Exists( "$::GBE_CONFIG/PLATFORM", $base_target  ) )
1013
        {
7296 dpurdie 1014
            UniquePush (\@BUILD_BADNAME, $target ) unless ($target eq 'NOBUILD'); 
6276 dpurdie 1015
            $pInfo->{NOT_AVAILABLE} = 3;
1016
            $pInfo->{BADNAME} = 1;
279 dpurdie 1017
        }
1018
    }
1019
 
1020
    #
4551 dpurdie 1021
    #   Mark as NOT_AVAILABLE platforms that are not available on this machine
279 dpurdie 1022
    #
6276 dpurdie 1023
    if ($buildAvailability)
279 dpurdie 1024
    {
6276 dpurdie 1025
         $pInfo->{MACHTYPE} = $buildAvailability;
1026
         $pInfo->{NOT_AVAILABLE} = 1 unless ($buildAvailability eq $::GBE_MACHTYPE)
279 dpurdie 1027
    }
1028
 
6276 dpurdie 1029
    #
1030
    #   Extend the build information
1031
    #
279 dpurdie 1032
    unless ($pInfo->{NOT_AVAILABLE} )
1033
    {
6276 dpurdie 1034
        if ( my $build_cfg = Require( "$::GBE_CONFIG/PLATFORM", "${target}.cfg"  ) )
227 dpurdie 1035
        {
1036
            Verbose ("Processing(add) Platform Configuration file: $build_cfg");
6276 dpurdie 1037
            my $package_name = "${target}_Build";
227 dpurdie 1038
 
1039
            if ( $package_name->can('add_platform') )
1040
            {
1041
                Verbose ("Processing(add) Platform Configuration: $package_name");
1042
                $package_name->add_platform( $pInfo );
1043
            }
1044
            else
1045
            {
1046
                Debug ("Processing(add) Platform Configuration: $package_name. 'add_platform' function not found");
1047
            }
1048
        }
1049
    }
1050
 
1051
    #
1052
    #   If a product name has been provided then the platform is a product
1053
    #   and will need additional processing
1054
    #
1055
    if ( $pInfo->{PRODUCT} )
1056
    {
1057
        #
1058
        #   Create the platform name. Derived from the product and the target
1059
        #
1060
        $pInfo->{PLATFORM} = $pInfo->{PRODUCT} . '_' . $pInfo->{TARGET};
1061
 
1062
        #
1063
        #   Remember the product name
1064
        #
1065
        $BUILDPRODUCT{ $pInfo->{PRODUCT} } = 1;
1066
 
1067
        #
1068
        #   Add platform name to the alias explansion being created
1069
        #   Allows the user to reference the entire FAMILY of platforms
1070
        #
1071
        HashJoin( \%BUILDALIAS, ' ', $pInfo->{PRODUCT}, $pInfo->{PLATFORM} );
1072
 
1073
        #
1074
        #   Create an element to assist in creating %ScmBuildProducts
1075
        #
1076
        $pInfo->{ISPRODUCT} = 1;
1077
        $BUILDPRODUCT_PARTS{$pInfo->{PLATFORM}} = "$pInfo->{PRODUCT},$pInfo->{TARGET}";
1078
    }
1079
    else
1080
    {
1081
        $pInfo->{PRODUCT} = $pInfo->{TARGET};
1082
        $pInfo->{PLATFORM} = $pInfo->{TARGET};
1083
    }
1084
 
1085
    #---------------------------------------------------------------------------
1086
    #   All the hard work has been done
1087
    #   We now know the platforms full name
1088
    #
1089
    #   Ensure that the target platform has not been been specified
1090
    #   Perhaps this should be an error
1091
    #
1092
    my $platform = $pInfo->{PLATFORM};
1093
 
5109 dpurdie 1094
    if ( defined ( $BUILDINFO{$platform}) && ! $Clobber)
227 dpurdie 1095
    {
5867 dpurdie 1096
        abtWarning(1,"$fname() duplicate platform '$platform'");
5429 dpurdie 1097
        return;
227 dpurdie 1098
    }
1099
 
1100
    #
1101
    #   Add platform (tag) to various lists
1102
    #
6276 dpurdie 1103
    UniquePush( \@BUILDPLATFORMS, $platform )    unless exists ($pInfo->{BADNAME});
227 dpurdie 1104
    UniquePush( \@DEFBUILDPLATFORMS, $platform ) unless ( $pInfo->{NOT_DEFAULT} );
1105
 
1106
    #
1107
    #   Create a simple alias if requested
1108
    #   Used if a platform creates multiple entires
1109
    #
1110
    if ( $pInfo->{ALIAS} )
1111
    {
317 dpurdie 1112
        HashJoin( \%BUILDALIAS_DELAY, ' ', $_, $platform )
1113
            foreach ( ArrayList($pInfo->{ALIAS}) );
227 dpurdie 1114
    }
1115
 
363 dpurdie 1116
    if ( $pInfo->{USERALIAS} )
1117
    {
1118
        HashJoin( \%BUILDALIAS_DELAY, ' ', $_, $platform )
1119
            foreach ( ArrayList($pInfo->{USERALIAS}) );
1120
    }
1121
 
227 dpurdie 1122
    #
1123
    #   Create the 'parts' of the platform. This is a list of unique
1124
    #   bits to search. It will consist of:
1125
    #       [0]     - platform
1126
    #       [1]     - product
1127
    #       ...     - Uses bits ...
1128
    #       [last]  - target
1129
    #
1130
    my @parts;
1131
 
379 dpurdie 1132
    if ( $pInfo->{USES_FIRST} )
1133
    {
1134
        UniquePush (\@parts, @{$pInfo->{USES_FIRST}} );
1135
    }
1136
 
1137
    UniquePush (\@parts, $platform);
1138
 
227 dpurdie 1139
    #
1140
    #   Include all the product extensions
1141
    #
1142
    if ( $pInfo->{ISPRODUCT}  )
1143
    {
1144
        UniquePush (\@parts, map {+ "$pInfo->{PRODUCT}_${_}" } @{$pInfo->{USES}});
1145
        UniquePush (\@parts, map {+ "$pInfo->{PRODUCT}_${_}" } @{$pInfo->{ALSO_USES}});
1146
        UniquePush (\@parts, $pInfo->{PRODUCT} );
1147
    }
1148
 
1149
    #
1150
    #   Add in non-product expanded parts
1151
    #
1152
    UniquePush (\@parts, @{$pInfo->{EXTRA_USES}});
1153
 
1154
    #
1155
    #   Create a structure to assist in search path resolution
1156
    #   The order is important. It sets the include search order for include
1157
    #   files and libraries
1158
    #   If A uses B then search in A_B, A, B
1159
    #       ie: GAK uses MOS68K Search stuff in GAK_MOS68K, GAK, MOS68K
1160
    #
1161
    #       Usage:  OBFTP uses TP5 on MOSCF(target)       (BuildProduct)
1162
    #       Expansion: OBFTP, TP5_MOSCF, TP5
1163
    #
1164
    #       Usage: VS2003(target) also uses WIN32(uses)     (BuildPlatform)
1165
    #       Expansion: VS2003, VS2003_WIN32, WIN32
1166
    #
1167
    if ( $pInfo->{ISPRODUCT}  )
1168
    {
1169
        UniquePush (\@parts, map {+ "${_}_$pInfo->{TARGET}", $_, $pInfo->{TARGET}} @{$pInfo->{USES}});
1170
        UniquePush (\@parts, map {+ "${_}_$pInfo->{TARGET}", $_, $pInfo->{TARGET}} @{$pInfo->{ALSO_USES}});
1171
    }
1172
    else
1173
    {
1174
        UniquePush (\@parts, map {+ "$pInfo->{TARGET}_${_}", $pInfo->{TARGET}, $_} @{$pInfo->{USES}});
1175
        UniquePush (\@parts, map {+ "$pInfo->{TARGET}_${_}", $pInfo->{TARGET}, $_} @{$pInfo->{ALSO_USES}});
1176
    }
1177
 
1178
    #
1179
    #   Finally - the target
1180
    #
1181
    UniquePush (\@parts, $pInfo->{TARGET} );
1182
 
1183
    #
1184
    #   Save the PARTS
1185
    #   Also saved as BUILDPLATFORM_PARTS for interface with older versions
1186
    #   of the deployments scripts.
1187
    #
1188
    $pInfo->{PARTS} = \@parts;
1189
 
1190
    #
1191
    #   Add any arguments to the platforms argument list
1192
    #
1193
    PlatformArgument( $platform, @{$pInfo->{ARGS}} ) if ( $pInfo->{ARGS} );
1194
 
1195
    #
1196
    #   Clean up and save
1197
    #
1198
    delete $pInfo->{TEMPLATE};
1199
    delete $pInfo->{FNAME};
1200
    $BUILDINFO{$platform} = $pInfo;
1201
#    DebugDumpData("BUILDINFO", \%BUILDINFO );
1202
}
1203
 
1204
 
1205
sub BuildArgument
1206
{
1207
    my( $platform, @arguments ) = @_;
1208
 
1209
    Debug( "BuildArgument($platform, @arguments)" );
6276 dpurdie 1210
    Error( "BuildArgument must appear before BuildName()..." ) if ( $BUILDNAME ne "" );
227 dpurdie 1211
 
1212
    #
6276 dpurdie 1213
    #   Just save the arguments for later processing
227 dpurdie 1214
    #
6276 dpurdie 1215
    push @BUILDARGUMENTS, \@_;
1216
}
227 dpurdie 1217
 
6276 dpurdie 1218
#-------------------------------------------------------------------------------
1219
# Function        : ProcessBuildArgument  
1220
#
1221
# Description     : Process BuildArgument operations
1222
#                   This needs to be done AFTER aliases have been created (cleaned up )
1223
#
1224
# Inputs          : Global data: @BUILDARGUMENTS 
1225
#
1226
# Returns         : 
1227
#
1228
sub ProcessBuildArgument 
1229
{
1230
    foreach my $set ( @BUILDARGUMENTS )
227 dpurdie 1231
    {
6276 dpurdie 1232
        my ($platform, @arguments ) = @{$set};
1233
        my @platforms;
1234
        #
1235
        #   Allow a wildcard to apply a single argument to all platforms
1236
        #   Should only be used AFTER all the platforms have been specified
1237
        #
1238
        if ( $platform eq '*' )
1239
        {
1240
            @platforms = @BUILDPLATFORMS;          # Simple Wildcard
1241
        }
1242
        else
1243
        {
1244
            @platforms = ExpandPlatforms( $platform );  # aliasing
1245
        }
227 dpurdie 1246
 
6276 dpurdie 1247
        foreach my $platform ( @platforms )
1248
        {
1249
            next if ( $platform =~ /^--/ );         # argument, ignore
1250
            PlatformArgument( $platform, @arguments );
1251
        }
227 dpurdie 1252
    }
1253
}
1254
 
1255
 
1256
sub BuildPlatforms
1257
{
1258
    my( @arguments ) = @_;
1259
    my $fname = "BuildPlatforms";
1260
 
1261
    Debug( "BuildPlatforms(@arguments)" );
1262
 
1263
    Error( "BuildPlatforms must appear before BuildName()..." )
1264
        if ( $BUILDNAME ne "" );
1265
 
1266
    #
1267
    #   Expand the user specified platforms to allow the use of BuildAlias
1268
    #   The (bad) side effect of this is that platform options get reorganised
1269
    #       PLATFORM,--Uses=ANOTHER  ==> PLATFORM --Uses=ANOTHER
1270
    #
6276 dpurdie 1271
    #   Insert markers(++) into @arguments to mark when to process collected data
227 dpurdie 1272
    #   Insert before each PLATFORM and at the end of the list
1273
    #   platform specifier or the end of the list. Scan the arguments
1274
    #
1275
    @arguments = ExpandPlatforms( @arguments );
1276
    my @new_args;
1277
    foreach  ( @arguments )
1278
    {
1279
        push (@new_args, '++') unless ( m/^--/ );
1280
        push (@new_args, $_ );
1281
    }
1282
    push (@new_args, '++');
1283
    shift @new_args if $new_args[0] eq '++';
1284
 
1285
 
1286
    my $platform  = "";                         # current platform
1287
    my $notdefault  = 0;
1288
    my @pargs = ();
1289
 
1290
    foreach my $arg ( @new_args )
1291
    {
1292
        #
1293
        #   Extract known options
1294
        #   Unknown options bind to the current platform
1295
        #
1296
        if ( $arg =~ /^--/ ) {
1297
            if ( $arg =~ /^--NotDefault$/ ) {
1298
                $notdefault = 1;
1299
 
1300
            } elsif ( $arg =~/^--FunctionName=(.*)/ ) {
1301
                $fname = $1;
1302
 
1303
            } else {
1304
                push @pargs, $arg;
1305
            }
1306
            next;
1307
        }
1308
 
1309
        #
1310
        #   New platform. Save name for later. Collect arguments first
1311
        #
1312
        unless ( $arg eq '++' )
1313
        {
1314
            $platform = $arg;
1315
 
1316
            Error( "$fname() missing platform specification" )
1317
                unless ( $platform );
1318
 
1319
            Error( "$fname() product '$platform' contains invalid characters" )
1320
                unless ( $platform eq quotemeta( $platform ) );
1321
 
1322
            next;
1323
        }
1324
 
1325
        #
1326
        #   Create new platform
1327
        #   Have collected name and arguments
1328
        #
6192 dpurdie 1329
        CreateBuildPlatformEntry($fname, $notdefault, undef, $platform, \@pargs  );
227 dpurdie 1330
 
1331
        #
1332
        #   Reset collection variables for next platform
1333
        #
1334
        $platform = "";
1335
        $notdefault  = 0;
1336
        @pargs = ();
1337
    }
1338
}
1339
 
1340
 
1341
#   PlatformArgument ---
1342
#       Append an argument list to the specified platform argument list.
1343
#       Internal use only
1344
#..
1345
 
1346
sub PlatformArgument
1347
{
1348
    my( $platform, @arguments ) = @_;
1349
 
1350
    Debug( "  PlatformArguments($platform, @arguments)" );
1351
 
1352
    HashJoin( \%BUILDPLATFORMARGS, $;, $platform, @arguments )
1353
        if ( $platform );
1354
}
1355
 
279 dpurdie 1356
#-------------------------------------------------------------------------------
5679 dpurdie 1357
# Function        : BuildExclude 
1358
#
1359
# Description     : Allow specific platforms to be excluded from the Build
1360
#                   Intended use:
1361
#                       Allow the use if a platform alias, but not all elements of it
1362
#                       ie: Use DEVLINUX, but not ARM9TDMI as we no longer support it 
1363
#                           in this version.
1364
#                   Multiple BuildExclude directives are allowed
1365
#                   Order or location is not important        
1366
#
1367
# Inputs          : Platforms names and options
6276 dpurdie 1368
#                       zzzz                Build Platform Name
1369
#                       INSTRUMENT          (Keyword - no instrumented builds)
5679 dpurdie 1370
#                       
1371
#
1372
# Returns         : Nothing 
1373
#
1374
sub BuildExclude
1375
{
1376
    my( @arguments ) = @_;
1377
    Debug( "BuildExclude(@arguments)" );
1378
 
1379
    Error( "BuildExclude must appear before BuildName()..." )
1380
        if ( $BUILDNAME ne "" );
1381
 
1382
    #
1383
    #   Simply save the arguments for later
1384
    #   Allow multiple specs in the one definition
1385
    #
1386
    foreach ( @arguments)
1387
    {
6276 dpurdie 1388
        Error ("Invalid format: $_") if m/[\s]/;
5679 dpurdie 1389
        UniquePush (\@BUILDEXCLUDE, split(/\s*,\s*/,$_));
1390
    }
1391
}
1392
 
1393
#-------------------------------------------------------------------------------
6133 dpurdie 1394
# Function        : BuildToolset 
1395
#
1396
# Description     : Indicate that this package will build binary parts of a JATS
1397
#                   toolset.
1398
#                   
1399
#                   Should be used to indicate that it building non-binary parts
1400
#                   too.
1401
#                   
1402
#                   Used as a sanity test.
1403
#
1404
# Inputs          : Options to limit the Machine Types affected 
1405
#
1406
# Returns         : 
1407
#
1408
sub BuildToolset
1409
{
1410
    my( @arguments ) = @_;
1411
 
1412
    $genToolsetPlatform = 1;
1413
    Debug( "BuildToolset(@arguments)" );
1414
    Error( "BuildToolset must appear before BuildName()..." )
1415
        if ( $BUILDNAME ne "" );
1416
 
1417
    #
1418
    #   Process TOOLSET specific options
1419
    #       --ExcludeMachType=xxxx,yyy
1420
    #       --MachType=xxxx,yyy
1421
    #
7296 dpurdie 1422
    $toolsetData->{enableToolset} = 1;
6133 dpurdie 1423
    foreach ( @arguments )
1424
    {
1425
        if ( m~^--ExcludeMachType=(.+)~i ) {
1426
            foreach my $arch (split(',',$1))
1427
            {
7296 dpurdie 1428
                ReportError("BuildToolset: Unknown MachType: $arch") unless PlatformConfig::validMachType($arch);
1429
                $toolsetData->{exclude}{lc $arch} = 1;
1430
                if (lc($arch) eq lc($::GBE_MACHTYPE))
6133 dpurdie 1431
                {
1432
                    Verbose("Exclude TOOLSET on this machine");
7296 dpurdie 1433
                    $toolsetData->{excludeThis} = lc($arch);
6133 dpurdie 1434
                }
1435
            }
1436
        } elsif ( m~^--MachType=(.+)~i ) {
1437
            foreach my $arch (split(',',$1))
1438
            {
7296 dpurdie 1439
                ReportError("BuildToolset: Unknown MachType: $arch") unless PlatformConfig::validMachType($arch);
1440
                $toolsetData->{include}{lc $arch} = 1;
1441
                if (lc($arch) eq lc($::GBE_MACHTYPE))
6133 dpurdie 1442
                {
1443
                    Verbose("Include TOOLSET on this machine");
7296 dpurdie 1444
                    $toolsetData->{includeThis} = lc($arch);
6133 dpurdie 1445
                }
1446
            }
1447
 
1448
        } else {
7296 dpurdie 1449
            ReportError ("BuildToolset: Unknown option: $_");
6133 dpurdie 1450
        }
1451
    }
1452
 
7296 dpurdie 1453
    if ( exists $toolsetData->{exclude} && exists $toolsetData->{include}) {
1454
        ReportError ("BuildToolset: Cannot use both --MachType and --ExcludeMachType");
1455
    }
1456
    ErrorDoExit();
1457
 
6133 dpurdie 1458
    #
1459
    #   Show we build for this architecture
7296 dpurdie 1460
    #   Have three conditions:
1461
    #       1) Current machType specifically excluded
1462
    #       2) Current machtype specifically included
1463
    #       3) Neither - further processing required
6133 dpurdie 1464
    #
1465
    $genToolsetActive = 0;
7296 dpurdie 1466
    if (exists $toolsetData->{excludeThis}) {
6133 dpurdie 1467
        $toolsetPlatform = 'Excluded';
1468
        return;
1469
    }
1470
 
7296 dpurdie 1471
    if (exists $toolsetData->{include}) {
1472
        if (exists $toolsetData->{includeThis}) {
6133 dpurdie 1473
            $genToolsetActive = 1;
1474
        } else {
1475
            $toolsetPlatform = 'Not included';
1476
        }
1477
        return;
1478
    }
1479
 
1480
    $genToolsetActive = 1;
1481
    return;
1482
}
1483
 
1484
 
1485
#-------------------------------------------------------------------------------
279 dpurdie 1486
# Function        : BuildName
1487
#
1488
# Description     : Defines the package name and version
1489
#
1490
# Inputs          : build arguments
1491
#                   Various formats are allowed for backward compatability
1492
#                   Must support a number of different formats
1493
#                       "name nn.nn.nn prj"
1494
#                       "name nn.nn.nn.prj"
1495
#
1496
#                       "name nn.nn.nn prj", "nn.nn.nn"
1497
#                       "name nn.nn.nn.prj", "nn.nn.nn"
1498
#
1499
#                       "name", "nn.nn.nn.prj"
1500
#
1501
#                       "name", "nn.nn.nn", "prj", --RelaxedVersion
1502
#
1503
# Returns         : Nothing
1504
#
227 dpurdie 1505
sub BuildName
1506
{
1507
    my( @arguments ) = @_;
1508
    my $relaxed_version_name = 0;
1509
    my @args;
1510
 
1511
    Debug( "BuildName(@arguments)" );
315 dpurdie 1512
    Error( "Platform(s) not defined.",
227 dpurdie 1513
            "BuildAlias, BuildProduct and BuildPlatform directives must be defined prior to BuildName()." )
1514
        unless( scalar @BUILDPLATFORMS );
1515
 
1516
#.. Parse arguments
1517
#.
1518
    my $build_info = parseBuildName( @arguments );
1519
 
1520
    $BUILDNAME_PACKAGE = $build_info->{BUILDNAME_PACKAGE};
1521
    $BUILDNAME_VERSION = $build_info->{BUILDNAME_VERSION};
1522
    $BUILDNAME_PROJECT = $build_info->{BUILDNAME_PROJECT};
359 dpurdie 1523
    $BUILDNAME_SUFFIX  = $BUILDNAME_PROJECT ? '.' . $BUILDNAME_PROJECT : '';
227 dpurdie 1524
 
1525
    $BUILDNAME         = $build_info->{BUILDNAME};
1526
    $BUILDVERSION      = $build_info->{BUILDVERSION};
6511 dpurdie 1527
    $BUILDBASEVERSION  = $build_info->{BUILDNAME_BASE_VERSION};
227 dpurdie 1528
 
1529
    $DEPLOY_PATCH      = $build_info->{DEPLOY_PATCH} || 0;
1530
 
1531
    #
1532
    #   Clobber processing done after values have been accumulated
1533
    #   as they may be used later
1534
    #
1535
    return if ( $Clobber );
7296 dpurdie 1536
    ToolsetFiles::AddFile('build.log') unless ($BuildInfo);
4003 dpurdie 1537
 
359 dpurdie 1538
    #
1539
    #   Determine type of sandbox
1540
    #
1541
    $sandbox_exact = ( -f $::GBE_DPKG_SBOX . '/.exact' )
1542
        if ( $::GBE_DPKG_SBOX );
1543
 
227 dpurdie 1544
#.. Create build.log summary information
1545
#
261 dpurdie 1546
    my ($sep) = "\n".(" " x 11) . ". ";
227 dpurdie 1547
 
261 dpurdie 1548
    Log( "\nBuild configuration (version $::GBE_VERSION)" );
1549
    Log( "Name ....... $BUILDNAME ($ScmHost)" );
1550
    Log( "Version .... $BUILDNAME_VERSION" );
1551
    Log( "DeployPatch. $DEPLOY_PATCH" ) if ($DEPLOY_PATCH);
1552
    Log( "Project .... $BUILDNAME_PROJECT" )if ($BUILDNAME_PROJECT);
1553
    Log( "Project .... ****** Specifically supressed ******" )unless ($BUILDNAME_PROJECT);
1554
    Log( "DateTime ... $::CurrentTime" );
1555
    Log( "AutoBuild... Enabled:$::GBE_ABT" ) if defined($::GBE_ABT) ;
7447 dpurdie 1556
    Log( "Legacy Mode. Enabled" ) if $::LegacyMode;
1557
 
6276 dpurdie 1558
    Log( "Build dir... $CwdFull" ) if defined($::GBE_ABT) || $::GBE_DPKG_SBOX;
4161 dpurdie 1559
    Log( "Build Mach.. $::GBE_HOSTNAME" ) if defined($::GBE_ABT);
6276 dpurdie 1560
    Log( "Build Cmd .. $CmdSwitch") if $CmdSwitch;
7296 dpurdie 1561
    Log( "Build Info . $BuildInfoFile") if $BuildInfo;
227 dpurdie 1562
 
359 dpurdie 1563
    Log( "PERL ....... $::GBE_PERL" );
261 dpurdie 1564
    Log( "BIN  ....... $::GBE_BIN" );
1565
    Log( "TOOLS ...... $::GBE_TOOLS" );
1566
    Log( "CONFIG ..... $::GBE_CONFIG" );
1567
    Log( "MACHTYPE ... $::GBE_MACHTYPE" );
227 dpurdie 1568
 
261 dpurdie 1569
    Log( "PLATFORM ... " . PrintList([split(' ', $::GBE_PLATFORM)], $sep) )    if defined ($::GBE_PLATFORM);
5708 dpurdie 1570
    Log( "EXCLUDE .... " . PrintList([@BUILDEXCLUDE], $sep) )    if (@BUILDEXCLUDE);
261 dpurdie 1571
    Log( "BUILDFILTER. " . PrintList([split(' ', $::GBE_BUILDFILTER)], $sep) ) if defined ($::GBE_BUILDFILTER);
227 dpurdie 1572
 
261 dpurdie 1573
    Log( "DPKG_STORE.. $::GBE_DPKG_STORE" );
1574
    Log( "DPKG ....... $::GBE_DPKG" );
4688 dpurdie 1575
    Log( "DPKG_REPLI . $::GBE_DPKG_REPLICA" );
6276 dpurdie 1576
    Log( "DPKG_ESCROW. $::GBE_DPKG_ESCROW" ) if $::GBE_DPKG_ESCROW;
261 dpurdie 1577
    Log( "DPKG_CACHE . $::GBE_DPKG_CACHE" );
1578
    Log( "DPKG_LOCAL . $::GBE_DPKG_LOCAL" );
1579
    Log( "DPKG_SBOX .. $::GBE_DPKG_SBOX" );
359 dpurdie 1580
    Log( "Sandbox .... " . ($sandbox_exact ? "Exact" : "Development") );
6198 dpurdie 1581
    Log( "LocalFilter. $::GBE_DPKG_SBOX/buildfilter") if ( $::GBE_DPKG_SBOX && -f $::GBE_DPKG_SBOX . '/buildfilter' );
227 dpurdie 1582
 
1583
    #
1584
    #   Generate a list of active platforms
1585
    #   Ensure that there are some active platforms
1586
    #
6276 dpurdie 1587
    ProcessBuildExclude();
227 dpurdie 1588
    GeneratePlatformList();
6133 dpurdie 1589
    Log( "Platforms .. " . PrintPlatforms(\@BUILDPLATFORMS, $sep) );
4551 dpurdie 1590
 
1591
    #
1592
    #   Detect a mix of Generic and non Generic targets
1593
    #       Cannot mix generic and non-generic targets
1594
    #
7296 dpurdie 1595
    if ($#GENERIC_TARGETS >= 0 && $#BUILDPLATFORMS >= 0)
4551 dpurdie 1596
    {
7296 dpurdie 1597
        if ($#BUILDPLATFORMS != $#GENERIC_TARGETS )
4551 dpurdie 1598
        {
1599
            Verbose("Active:", @BUILD_ACTIVEPLATFORMS);
1600
            Verbose("Generic:", @GENERIC_TARGETS);
1601
            Error("Cannot mix GENERIC and non-GENERIC targets in the one build");
1602
        }
1603
    }
1604
 
4778 dpurdie 1605
    #
6133 dpurdie 1606
    #   Build System Generic Sanity Test
4778 dpurdie 1607
    #       If Generic   then MUST be a GENERIC build
1608
    #       If NoGeneric then MUST not be a GENERIC build
1609
    #
1610
    if (defined $GenericBuild)
1611
    {
1612
        if ( scalar(@GENERIC_TARGETS) ne $GenericBuild)
1613
        {
1614
            Error("Generic build inconsistency",
1615
                  "Release Manager entry indicates: $GenericBuild",
1616
                  "Build File indicates: " . scalar(@GENERIC_TARGETS)
1617
                  );
1618
        }
1619
    }
1620
 
4003 dpurdie 1621
    unless( @BUILD_ACTIVEPLATFORMS )
1622
    {
5109 dpurdie 1623
        my $msg = 'GBE_BUILDFILTER prevents any targets being built';
6133 dpurdie 1624
        if (defined($::GBE_ABT) || defined($::GBE_SANDBOX )) {
227 dpurdie 1625
 
4003 dpurdie 1626
            # Build filter on this machine prevents the package building
1627
            # On a Build System this is not an error
1628
            #   Create a dummy platform called NOBUILD
1629
            #   Do not populate the interface directory with package data
1630
            #   Flag for jmake to do very little
1631
            #
1632
            CreateBuildPlatformEntry('Internal', 0, undef, 'NOBUILD');
1633
            $IgnorePkgs = 1;
1634
            $NoBuild = 1;
6276 dpurdie 1635
            $genToolsetActive = 0;
5109 dpurdie 1636
            Log( "Build for .. ". PrintPlatforms(['NOBUILD - ' . $msg], $sep));
4003 dpurdie 1637
 
1638
        } else {
5109 dpurdie 1639
            Error( $msg );
4003 dpurdie 1640
        }
1641
    }
1642
    else
1643
    {
1644
        Log( "Build for .. ". PrintPlatforms(\@BUILD_ACTIVEPLATFORMS, $sep));
1645
    }
1646
 
6133 dpurdie 1647
    ProcessToolSetPlatform() if $genToolsetActive;
1648
    Log( "Toolset .... " . $toolsetPlatform ) if $genToolsetPlatform;
1649
    Error ("No suitable TOOLSET platform found") if (($genToolsetActive > 1) && $::GBE_ABT);
1650
 
227 dpurdie 1651
    #
1652
    #   Generate an error if nothing can be done because the GBE_PLATFORM
1653
    #   masks any useful operation.
1654
    #
1655
    if ( $::GBE_PLATFORM )
1656
    {
1657
        my @MAKE_PLATFORMS;
1658
        my %active_platforms;
1659
 
239 dpurdie 1660
        #
1661
        #   Create a hash of active platforms based on the array of
1662
        #   active platforms to simplify testing
1663
        #
1664
        $active_platforms{$_} = 1 foreach ( @BUILD_ACTIVEPLATFORMS  );
227 dpurdie 1665
 
4551 dpurdie 1666
        unless ( $#GENERIC_TARGETS >= 0 )
227 dpurdie 1667
        {
239 dpurdie 1668
            foreach  ( split( ' ', $::GBE_PLATFORM) )
1669
            {
1670
                push @MAKE_PLATFORMS, $_
1671
                    if ( $active_platforms{$_} );
1672
            }
227 dpurdie 1673
 
239 dpurdie 1674
            Error ("The GBE_PLATFORM filter prevents any targets being made",
1675
                   "GBE_PLATFORM: $::GBE_PLATFORM" ) unless ( @MAKE_PLATFORMS );
227 dpurdie 1676
 
261 dpurdie 1677
            Log( "Make for ... ". PrintPlatforms(\@MAKE_PLATFORMS, $sep));
239 dpurdie 1678
        }
227 dpurdie 1679
 
1680
    }
1681
 
6276 dpurdie 1682
    #
1683
    #   NoBuilds do not generate warnings
1684
    #
7296 dpurdie 1685
    return if $NoBuild && !$BuildInfo;
6276 dpurdie 1686
 
1687
    #
1688
    #   Generate a list of platforms that are completely unknown to JATS
1689
    #   May be the result of a user typo or a guess
1690
    #
1691
    if ( @BUILD_BADNAME )
1692
    {
1693
        Log( "Unknown Pl . " . PrintPlatforms(\@BUILD_BADNAME, $sep) );
7262 dpurdie 1694
        abtWarning (1,"The following platform names are not known to JATS", "@BUILD_BADNAME");
6276 dpurdie 1695
    }
1696
 
1697
    #
1698
    #   Detect multiple GENERIC targets
1699
    #       Only one such target can be processed on any one machine
1700
    #
1701
    if ($#GENERIC_TARGETS > 0)
1702
    {
1703
        Error ("Multiple GENERIC targets detected", PrintPlatforms(\@GENERIC_TARGETS, $sep));
1704
    }
1705
 
7296 dpurdie 1706
    generateBuildInfo() if ($BuildInfo);
227 dpurdie 1707
    return 1;
1708
}
1709
 
6133 dpurdie 1710
#-------------------------------------------------------------------------------
7296 dpurdie 1711
# Function        : generateBuildInfo 
1712
#
1713
# Description     : Using in BuildInfo mode to save the required information
1714
#
1715
#                   In BuildInfo mode we have all the data that we need
1716
#                   Save it into a file for the build system and then exit the build process
1717
#                   We do not need to do any further work at this point in time
1718
#
1719
# Inputs          : Globals 
1720
#
1721
# Returns         : This function does not return
1722
#                   It will exit as there is no more work to be done
1723
#                   
1724
#                   Will generate a JAVA properties file with BuildInfo required by the
1725
#                   Build System.
1726
#
1727
sub generateBuildInfo
1728
{
1729
    DumpCapture();
1730
    Message ("Generate BuildInfo Data: ". $BuildInfoFile);
1731
    my @propLines = ();
1732
 
1733
 
1734
    my $fh = ConfigurationFile::New( $BuildInfoFile, '--Type=Properties' );
1735
    $fh->HeaderSimple( "buildlib (Version $BuildVersion)", "BuildInfo properties" );
1736
 
1737
    # Build style
1738
    push @propLines, "buildstyle = JATS";
1739
 
1740
    # Current Build Filter
1741
    push @propLines, "buildfilter = " . join(',', sort split(' ', $::GBE_BUILDFILTER));
1742
 
1743
    # All platforms that the package can be built for.
1744
    push @propLines, "platforms = " . join(',', sort @BUILDPLATFORMS);
1745
 
1746
    # All platforms that the package will be built for with the current build filter
1747
    my @AllCanBuild;
1748
    my %filterMap;
1749
    foreach ( split(' ', $::GBE_BUILDFILTER) ) {
1750
        $filterMap{$_} = 1;
1751
        my $genericMachType = PlatformConfig::getGenericMachType($_);
1752
        if ($genericMachType) {
1753
            $filterMap{$genericMachType} = 1;
1754
        }
1755
    }
1756
    push (@AllCanBuild, 'GENERIC') if ($#GENERIC_TARGETS >= 0);
1757
 
1758
    foreach ( @BUILDPLATFORMS ) {
1759
        if (exists $filterMap{$_}) {
1760
            push @AllCanBuild, $_;
1761
        }
1762
    }
1763
    push @propLines, "build.platforms = " . join(',', sort @AllCanBuild);
1764
 
1765
    # Platforms that have been specifically excluded from the build
1766
    push @propLines, "excluded.platforms = " . join(',', sort @BUILDEXCLUDE);
1767
 
1768
    # Platforms not known to JATS
1769
    # Only works in ABT mode. Errors will be detected before this
1770
    push @propLines, "unknown.platforms = " . join(',', sort @BUILD_BADNAME);
1771
 
1772
    # Toolset build information
1773
    CalcToolsetBuildInfo(@AllCanBuild);
1774
    if (exists $toolsetData->{platforms}) {
1775
        push @propLines, "toolset.platforms = " . join(',', sort @{$toolsetData->{platforms}});
1776
    }
1777
 
1778
    # Indication of production and debug builds
1779
    my (@OnlyProd, @OnlyDebug);
1780
    foreach my $platform ( sort keys %BUILDPLATFORMARGS) {
1781
        foreach my $arg ( split($;, $BUILDPLATFORMARGS{$platform})) {
1782
            push (@OnlyProd,  $platform) if ($arg =~ m~--OnlyProd~);
1783
            push (@OnlyDebug, $platform)  if ($arg =~ m~--OnlyDebug~);
1784
        }
1785
    }
1786
    push @propLines, "prod.platforms = " . join(',', sort @OnlyProd) ;
1787
    push @propLines, "debug.platforms = " . join(',', sort @OnlyDebug) ;
1788
 
1789
    # JAVA version specified
1790
    if ($BUILDPLATFORMARGS{JAVA}) {
1791
        foreach my $arg ( split($;, $BUILDPLATFORMARGS{JAVA})) {
1792
            if ($arg =~ m~^--Version=(.*)~i) {
1793
                push @propLines, "java.version = " . $1;
1794
                last;
1795
            }
1796
        }
1797
    }
1798
 
1799
    # The package is GENERIC
1800
    if ($#GENERIC_TARGETS >= 0) {
1801
        push @propLines, "generic.build = 1";
1802
    }
1803
 
1804
    $fh->WriteLn(@propLines);
1805
    $fh->Close();
1806
 
1807
    # Display for user gratification (and build system logging)
1808
    Information($BuildInfoFile,@propLines);
1809
    exit 0;
1810
}
1811
 
1812
#-------------------------------------------------------------------------------
6133 dpurdie 1813
# Function        : needToolset 
1814
#
1815
# Description     : Internal. Determine if this machine needs to build for
1816
#                   a TOOLSET or a GENERIC_<MachType>
1817
#                   
1818
#                   In Build System
1819
#                       BUILDFILTER must identify the machine performing TOOLSET builds
1820
#                       
1821
#                       The build filter MUST contain the psuedo platform TOOLSET in order for 
1822
#                       the alias to be created. This requires that the build daemons be configured to 
1823
#                       specify a TOOLSET. 
1824
#                       
1825
#                       Care MUST be taken to not configure multiple TOOLSET candiates 
1826
#                       on similar machine types.
1827
#                       
1828
#                   Non Build Sytem (User Development)
1829
#                       True    
1830
#
1831
# Inputs          : 
1832
#
1833
# Returns         : 
1834
#
1835
sub needToolset
1836
{
1837
    my $toolsetNeeded;
227 dpurdie 1838
 
6133 dpurdie 1839
    $toolsetNeeded = 1 if (!defined($::GBE_ABT));
1840
    if (!$toolsetNeeded && defined($::GBE_BUILDFILTER) ) {
1841
        $toolsetNeeded = grep( /^TOOLSET$/, split( ' ', $::GBE_BUILDFILTER ) );
1842
    }
1843
 
1844
    return $toolsetNeeded;
1845
}
1846
 
1847
#-------------------------------------------------------------------------------
1848
# Function        : ProcessToolSetPlatform 
1849
#
1850
# Description     : Locate the TOOLSET platform if required
1851
#                   In Build System
1852
#                       BUILDFILTER must identify the machine performing TOOLSET builds
1853
#                       The first suitable target will be chosen
1854
#                       
1855
#                       The build filter MUST contain the psuedo platform TOOLSET in order for 
1856
#                       the alias to be created. This requires that the build daemons be configured to 
1857
#                       specify a TOOLSET. 
1858
#                       
1859
#                       Care MUST be taken to not configure multiple TOOLSET candiates 
1860
#                       on similar machine types.
1861
#                       
1862
#                   Non Build Sytem (User Development)
1863
#                       The first suitable target will be chosen    
1864
#
1865
# Inputs          : 
1866
#
1867
# Returns         : 
1868
#
1869
sub ProcessToolSetPlatform
1870
{
1871
    my $toolsetNeeded;
1872
    my $toolset;
1873
 
1874
    #
1875
    #   User is not allowed to create a TOOLSET alias
1876
    #       This should be captured before here, but ...
1877
    #
1878
    if (exists $BUILDALIAS{TOOLSET})
1879
    {
1880
        Error('Internal: User has manually specified a TOOLSET alias' );
1881
    }
1882
 
1883
    #
1884
    #   Determine if we need to do any work
1885
    #
1886
    return unless needToolset();
1887
 
1888
    #
1889
    #   Need to ensure that we have a TOOLSET platform in the build set
1890
    #
1891
    my %activePlatformMap = map {$_ => 1} @BUILD_ACTIVEPLATFORMS;
7296 dpurdie 1892
    my @toolsetTargets = PlatformConfig::getTargetsByTag('TOOLSET');
6133 dpurdie 1893
    foreach my $item (@toolsetTargets)
1894
    {
1895
        if (exists($activePlatformMap{$item}))
1896
        {
1897
            #
1898
            #   Add TOOLSET arguments into the existing target
1899
            #   Really only expecting --OnlyProd
1900
            #
1901
            if ( @genToolsetArgs) {
1902
                PlatformArgument($item, @genToolsetArgs);
1903
            }
1904
 
1905
            # Update the displayed Toolset platform
1906
            $toolset = $item;
1907
            $toolsetPlatform = $toolset;
1908
            last;
1909
        }
1910
    }
1911
 
1912
    #
1913
    #   No toolset platform found in the current build set
1914
    #   
1915
    unless ($toolset) {
1916
        $toolsetPlatform = "None found in current build set"; 
1917
        $genToolsetActive = 2;
1918
        return;
1919
    }
1920
 
1921
    #
1922
    #   Insert alias information
1923
    #
1924
    $BUILDALIAS{TOOLSET} = $toolset;
1925
    push @{$BUILDINFO{$toolset}{USERALIAS}}, 'TOOLSET';
1926
}
1927
 
1928
#-------------------------------------------------------------------------------
7296 dpurdie 1929
# Function        : CalcToolsetBuildInfo 
1930
#
1931
# Description     : Calculate the Toolset component of the BuildInfo
1932
#                   Note: Similar to ProcessToolSetPlatform (above)
1933
#                   
1934
#                   Need to determine the most suitable platform for building toolsets. 
1935
#                   Only consider those that are a part of the build set
1936
#
1937
# Inputs          : AllPlatforms    - an Array of all platrform that this package can
1938
#                                     be built on with the current build filter 
1939
#
1940
# Returns         : 
1941
#
1942
sub  CalcToolsetBuildInfo {
1943
    my (@allPlatforms) = @_;
1944
    return unless $toolsetData->{enableToolset};
1945
 
1946
    my %toolsetSelected;
1947
    my %platformMap = map {$_ => 1} @allPlatforms;
1948
    my @toolsetTargets = PlatformConfig::getTargetsByTag('TOOLSET');
1949
    foreach my $item (@toolsetTargets)
1950
    {
1951
        if (exists($platformMap{$item}))
1952
        {
1953
            my $include = 0;
1954
            my $toolMachType = PlatformConfig::targetHasTag($item, 'MACHTYPE');
1955
 
1956
            # Specifically included
1957
            if (exists $toolsetData->{include}){
1958
                if (exists $toolsetData->{include}{ lc $toolMachType}) {
1959
                    $include = 1;
1960
                }
1961
            # Specifically excluded
1962
            } elsif (exists $toolsetData->{exclude}) {
1963
                unless (exists $toolsetData->{exclude}{ lc $toolMachType}) {
1964
                    $include = 1;
1965
                }
1966
            # Default
1967
            } else {
1968
                $include = 1;
1969
            }
1970
 
1971
            if ($include) {
1972
                unless (exists $toolsetSelected{$toolMachType}) {
1973
                    $toolsetSelected{$toolMachType} = $item;
1974
                    push @{$toolsetData->{platforms}}, $item;
1975
                }
1976
            }
1977
        }
1978
    }
1979
#DebugDumpData("toolsetSelected", \%toolsetSelected);
1980
}
1981
 
1982
#-------------------------------------------------------------------------------
6133 dpurdie 1983
# Function        : BuildPreviousVersion 
1984
#
1985
# Description     : Deprecated. Do not use 
1986
#
1987
# Inputs          : 
1988
#
1989
# Returns         : 
1990
#
227 dpurdie 1991
sub BuildPreviousVersion
1992
{
1993
    my( $version ) = shift;
1994
 
1995
    $BUILDPREVIOUSVERSION = $version;
261 dpurdie 1996
    Log( "Previous Version ... $BUILDPREVIOUSVERSION" );
227 dpurdie 1997
 
1998
    return 1;
1999
}
2000
 
2001
 
2002
sub BuildInterface
2003
{
2004
    my( $ifdirname ) = @_;
2005
 
2006
    #
2007
    #   Clobber the directory - at the end.
2008
    #
2009
    if ( $Clobber )
2010
    {
2011
        #
2012
        #   If this Interface directory contains the Dpackage.cfg file
2013
        #   then JATS has created DPACKAGE and it needs to be clobbered
2014
        #   Flag that it needs to be done later - when we know where it is
2015
        #
2016
        $DeleteDPACKAGE = 1 if ( -f "$ifdirname/Dpackage.cfg" );
2017
    }
2018
 
2019
    #
6133 dpurdie 2020
    #   Generate the required directory
227 dpurdie 2021
    #
6133 dpurdie 2022
    BuildInterfaceInternal($ifdirname);
2023
    Log( "Interface .. $ifdirname" );
2024
    return 1;
2025
}
227 dpurdie 2026
 
6133 dpurdie 2027
#-------------------------------------------------------------------------------
2028
# Function        : BuildInterfaceInternal  
2029
#
2030
# Description     : Internal Use Only
2031
#                   Guts of the BuildInterface processing 
2032
#
2033
# Inputs          : $ifdirname  - Name of an interface directory
2034
#
2035
# Returns         : 
2036
#
2037
 
2038
sub BuildInterfaceInternal
2039
{
2040
    my( $ifdirname ) = @_;
2041
    my @createDirs;
2042
 
2043
    push @CLOBBERDIRS, $ifdirname;
2044
 
227 dpurdie 2045
    if ( $ifdirname eq "local" ) {
6133 dpurdie 2046
        push @createDirs, "$ifdirname/inc";
227 dpurdie 2047
        $BUILDLOCAL = "local";
2048
 
2049
    } else {
6133 dpurdie 2050
        push @createDirs, "$ifdirname/include";
227 dpurdie 2051
        $BUILDINTERFACE = $ifdirname;
2052
        $::ScmInterface = $ifdirname;
6619 dpurdie 2053
 
2054
        #
2055
        #   Set up the local cache
2056
        #
2057
        my $iCache = "$ifdirname/dpkg_cache";
2058
        if ($BUILDINTERFACE && $opt_localCache) {
2059
            my $iCache = "$ifdirname/dpkg_cache";
2060
            push @createDirs, $iCache;
2061
 
2062
            $Cache = $opt_localCache;
2063
            $::GBE_DPKG_CACHE = FullPath($iCache);
2064
            $ENV{GBE_DPKG_CACHE} = $::GBE_DPKG_CACHE; 
2065
        } elsif (-d  $iCache ){
2066
            #$Cache = 1 if $Cache == 0;
2067
            $::GBE_DPKG_CACHE = FullPath($iCache);
2068
            $ENV{GBE_DPKG_CACHE} = $::GBE_DPKG_CACHE; 
2069
        }
227 dpurdie 2070
    }
2071
 
6133 dpurdie 2072
    unless ($Clobber) {
2073
        push @createDirs, "$ifdirname/bin";
2074
        push @createDirs, "$ifdirname/lib";
2075
 
2076
        foreach my $dir ( @createDirs)
2077
        {
2078
            mkpath($dir);
2079
        }
2080
        ToolsetFiles::AddDir($ifdirname, 'Internal');
2081
    }
227 dpurdie 2082
}
2083
 
2084
 
6133 dpurdie 2085
 
227 dpurdie 2086
sub BuildDirTree
2087
{
2088
    my( $dirfile, $dirhead ) = @_;
2089
    my( $dirname, $c );
2090
 
2091
    $dirhead = '.'
2092
        unless defined( $dirhead );
2093
 
2094
    if ( $Clobber )                             # clobber mode ?
2095
    {
2096
        push @CLOBBERDIRS, $dirhead unless $dirhead eq '.';
2097
        return;
2098
    }
2099
 
2100
    #
2101
    #   Allow for an empty "dirfile". This will allow a directory to be created
2102
    #   without the overhead of the file
2103
    #
2104
    if ( ! $dirfile )
2105
    {
261 dpurdie 2106
        Log( "DirTree .... $dirhead" );
341 dpurdie 2107
        mkpath ( $dirhead );
227 dpurdie 2108
    }
2109
    else
2110
    {
261 dpurdie 2111
        Log( "DirTree .... $dirfile within $dirhead" );
341 dpurdie 2112
        mkpath ( $dirhead );
2113
 
283 dpurdie 2114
        open( DIRFILE, '<' ,$dirfile ) ||
227 dpurdie 2115
            Error( "cannot open '$dirfile'" );
2116
 
2117
        while( $dirname = <DIRFILE> )
2118
        {
2119
            chop $dirname;
2120
            $dirname =~ s/#.*//;
2121
            $c = $dirname =~ s/\s*(\S+).*/$1/g;
2122
 
2123
            next unless ( $c == 1 );
2124
 
2125
            if ( ! -d "$dirhead/$dirname" )
2126
            {
261 dpurdie 2127
                Log( "Dir ........ $dirhead/$dirname" );
341 dpurdie 2128
                mkpath ( "$dirhead/$dirname" );
227 dpurdie 2129
            }
2130
        }
2131
 
2132
        close( DIRFILE );
2133
    }
2134
    $BUILDDIRTREE = $dirhead;
2135
}
2136
 
2137
#-------------------------------------------------------------------------------
2138
# Function        : IncludePkg
2139
#
2140
# Description     : Examine a fully specified package directory for a file
2141
#                   that will specify packages to be included. This allows
2142
#                   a package to be simply a package of other packages
2143
#
2144
#                   Internal function. Not to be used by users
2145
#
2146
# Inputs          : Name of the package
2147
#                   Full directory path of the package to examine
2148
#
2149
# Returns         : Nothing
2150
#
2151
sub IncludePkg
2152
{
2153
    my ($name, $pkg) = @_;
2154
    my $file = "$pkg/incpkg";
2155
 
363 dpurdie 2156
    Debug ("IncludePkg: $name, $pkg" );
227 dpurdie 2157
 
2158
    #
2159
    #   Using a require will ensure that the package is only processed once
2160
    #   even though the function user may be called multiple times.
2161
    #   Also prevents recursion within included packages.
2162
    #
2163
    if ( -f $file  )
2164
    {
261 dpurdie 2165
        Log( "PackageIncludes. $name" ) unless ( $INC{$file} );
227 dpurdie 2166
        require $file;
2167
    }
2168
}
2169
 
2170
#-------------------------------------------------------------------------------
2171
# Function        : LinkPkgArchive
2172
#
2173
# Description     : Include an external package into the build sandbox
2174
#                   by extending the compiler and linker search paths to
2175
#                   include suitable directories found in the package
2176
#
2177
# Inputs          : package name
2178
#                   package version
2179
#
2180
sub LinkPkgArchive
2181
{
2182
    my( $name, $version ) = @_;
2183
 
2184
    return BuildPkgArchive( @_ )
2185
        if ( $ForceBuildPkg );                  # Forcing interface directory
2186
    return if ( $Clobber );                     # clobber mode ?
2187
 
2188
    Debug( "LinkPkgArchive:" );
2189
    Debug( "Name:      $name" );
2190
    Debug( "Version:   $version" );
2191
 
2192
    DataDirective("LinkPkgArchive");            # This directive allowed here
2193
 
2078 dpurdie 2194
    if ( $IgnorePkgs )
2195
    {
2196
        Log( "LinkPkgArchive .. $name ($version) - Ignored" );
2197
        return;
2198
    }
2199
 
227 dpurdie 2200
    #
2201
    #   Ensure that we have do not have multiple definitions
2202
    #
2203
    if ( PackageEntry::Exists( $name, $version ) )
2204
    {
261 dpurdie 2205
        Log( "Duplicate Package: $name, $version. Duplicate entry ignored" );
227 dpurdie 2206
        return;
2207
    }
2208
 
2209
    if ( $Cache && $::GBE_DPKG_CACHE )
2210
    {
2211
        my $mode = ($Cache > 1) ? "-refresh" : "";
331 dpurdie 2212
        Log( "LinkPkgArchive .. $name ($version) Update Cache" );
5744 dpurdie 2213
        System('--NoExit', "$::GBE_PERL $::GBE_TOOLS/cache_dpkg.pl $mode -wait -quiet $name/$version" );
227 dpurdie 2214
    }
2215
 
2216
    #
2217
    #   Locate the package ONCE
2218
    #
331 dpurdie 2219
    Log( "LinkPkgArchive .. $name ($version)" );
6276 dpurdie 2220
    my ($pkg, $local, $pkgSig ) = PackageLocate( $name, $version );
227 dpurdie 2221
    if ( $pkg )
2222
    {
2223
        #
6276 dpurdie 2224
        #   Create a Package Entry
2225
        #
2226
        my $entry = PackageEntry::New( $pkg, $name, $version, 'link', $local, $pkgSig );
2227
 
2228
        #
227 dpurdie 2229
        #   Generate package rules for each active platform
2230
        #
363 dpurdie 2231
        IncludePkg ( $name, $pkg );
6276 dpurdie 2232
        foreach my $platform ( @BUILD_ACTIVEPLATFORMS ) {
2233
            LinkEntry( $platform, $entry );
227 dpurdie 2234
        }
2235
    }
2236
}
2237
 
2238
#-------------------------------------------------------------------------------
2239
# Function        : PackageLocate
2240
#
2241
# Description     : Locate a package
2242
#                   Once located a package will be processed for each
2243
#                   platform, but it need only be located ONCE
2244
#
2245
# Inputs          : package name
2246
#                   package version
2247
#
2248
# Returns         : path to the package
2249
#                   local       1 - From local package repository
6276 dpurdie 2250
#                   Package Signature
227 dpurdie 2251
#
2252
sub PackageLocate
2253
{
2254
    my ($name, $uversion ) = @_;
283 dpurdie 2255
    my $pkg;
227 dpurdie 2256
    my $local = 1;
359 dpurdie 2257
    my $sandbox = ! $sandbox_exact;
227 dpurdie 2258
    my $isa_cache = 0;
2259
    my $version;
2260
 
2261
    Debug( "PackageLocate: ($name/$uversion)" );
2262
 
2263
    #
2264
    #   Look in each package archive directory
2265
    #
2266
    foreach my $dpkg ( split( $::ScmPathSep, $::GBE_DPKG_SBOX),
2267
                       '--NotSandbox',
2268
                       split( $::ScmPathSep, $::GBE_DPKG_LOCAL),
2269
                       '--NotLocal',
2270
                       split( $::ScmPathSep, $::GBE_DPKG_CACHE),
2271
                       '--NotCache',
6276 dpurdie 2272
                       split( $::ScmPathSep, $::GBE_DPKG_ESCROW),
2273
                       '--NotEscrow',
4688 dpurdie 2274
                       split( $::ScmPathSep, $::GBE_DPKG_REPLICA),
227 dpurdie 2275
                       split( $::ScmPathSep, $::GBE_DPKG),
313 dpurdie 2276
                       split( $::ScmPathSep, $::GBE_DPLY),
227 dpurdie 2277
                       split( $::ScmPathSep, $::GBE_DPKG_STORE) )
2278
    {
2279
 
2280
        #
2281
        #   Detect various tags that have been placed in the search list
2282
        #   to flag the end of the sandbox search and the end of the local
2283
        #   archive search
2284
        #
2285
        if ( $dpkg eq '--NotSandbox' )
2286
        {
2287
            $sandbox = 0;
2288
            next;
2289
        }
2290
        if ( $dpkg eq '--NotLocal' )
2291
        {
2292
            $local = 0;
2293
            $isa_cache = 1;
2294
            next;
2295
        }
2296
        if ( $dpkg eq '--NotCache' )
2297
        {
2298
            $isa_cache = 0;
2299
            next;
2300
        }
6276 dpurdie 2301
        if ( $dpkg eq '--NotEscrow' )
2302
        {
2303
            last if ($::GBE_DPKG_ESCROW);
2304
            next;
2305
        }
2306
 
227 dpurdie 2307
        #
2308
        #   If we are playing in a sandbox, then the version number is
2309
        #   not used. The Package suffix is still used so that we can
2310
        #   differentiate sysbasetypes.xxxxx.mas and sysbasetypes.xxxxx.syd
2311
        #
2312
        if ( $sandbox )
2313
        {
359 dpurdie 2314
            my ($pn, $pv, $ps ) = SplitPackage ($name, $uversion );
227 dpurdie 2315
            $version = 'sandbox';
2316
            $version .= '.' . $ps if ( $ps );
2317
        }
2318
        else
2319
        {
2320
            $version = $uversion;
2321
        }
2322
 
6133 dpurdie 2323
        $pkg = "$dpkg/$name/$version";
2324
        $pkg = "$dpkg/$name/$version.lnk"
2325
            if ( -e "$dpkg/$name/$version.lnk" );
2326
 
227 dpurdie 2327
        #
2328
        #   Using a soft link
2329
        #   Emulate a link in software. The link file contains one line
2330
        #   which is the real pathname of the package
2331
        #
2332
        if ( $pkg =~ m~(.*)\.lnk$~  )
2333
        {
2334
            #
2335
            #   Warn the user if both a link and a real directory
2336
            #   are both present - the link may well be incorrect
2337
            #
2338
            my $non_link = $1;
2339
            Warning ("Suspect package link: $pkg",
2340
                     "Both a link and a package where found - using the link" )
2341
                                                            if ( -d $non_link );
2342
 
2343
            Debug( "           link found -> $pkg" );
2344
            my $link_src = $pkg;
6133 dpurdie 2345
            $pkg = TagFileRead($pkg);
2346
            $pkg =~ s~\\~/~g;
5819 dpurdie 2347
            if ($pkg =~ s~^GBE_SANDBOX/~$::GBE_SANDBOX/~)
2348
            {
6133 dpurdie 2349
                    $pkgFromSandbox++;
2350
 
5819 dpurdie 2351
                    # If the target sandbox is in the 'deploymode' then the package
2352
                    # will not be in the expected location. It will be in a 'build/deploy'
2353
                    # subdir. Remove the pkg/name dir to get to the root of the package
2354
                    my @dirs = File::Spec->splitdir( $pkg );
2355
                    splice(@dirs, -2);
2356
                    my $deployBox = catdir(@dirs, 'build', 'deploy');
2357
                    $pkg = $deployBox if ( -d $deployBox);
2358
            }
227 dpurdie 2359
 
2078 dpurdie 2360
            unless ( -d $pkg )
2361
            {
2362
                Error ("Broken link: $pkg",
2363
                       "Source link: $link_src",
2364
                       "Try deleting the .lnk file" ) unless ( $NoPackageError );
2365
 
2366
                Warning ("Package not available. Broken link: $pkg");
2367
            }
227 dpurdie 2368
        }
2369
 
2370
        Debug( "           searching $pkg" );
2371
 
2372
        #   Does the package directory exist?
2373
        #   Terminate the directory name with a "/" to detect hidden spaces
2374
        #..
2375
        $pkg =~ s~//~/~g;
2376
        next unless ( -d "$pkg/" );             # exists ?
2377
 
2378
        #
2379
        #   If the package exists within the dpkg_archive cache then mark the
2380
        #   version as having been used. Used by cache cleanup algorithms
2381
        #
2382
        if ( $isa_cache  )
2383
        {
2384
            TouchFile ( "$pkg/used.cache", "Marks the cache copy as being used");
6619 dpurdie 2385
            #print( "                  Cached -> $pkg\n" );
227 dpurdie 2386
        }
2387
 
2388
        #
2389
        #   Use the first suitable package found
2390
        #..
2391
 
2392
        Debug( "           importing $pkg" );
2393
        return $pkg, $local;
2394
    }
2395
 
2396
    #
2397
    #   Package not found
7452 dpurdie 2398
    #       This is an error, although it can be bypassed
2399
    #       In an sandbox it will be ignored if marked as a noBuild
2400
    #       
2401
    my( $link_dir, $base) = genSandboxFile(SplitPackage ($name, $uversion ));
2402
    if ( $link_dir ) {
2403
        my $nob_path  = "$link_dir/$base.nob";
2404
        if (-f $nob_path) {
2405
            Log( "WARNING .... Package flagged as noBuild: '$name/$version'" );
2406
            return;
2407
        }
2408
    }
2409
 
261 dpurdie 2410
    Error ("Required package not found: '$name/$version'" ) unless ( $NoPackageError );
227 dpurdie 2411
 
261 dpurdie 2412
    Log( "WARNING .... Package not available: '$name/$version'" );
283 dpurdie 2413
    return;
227 dpurdie 2414
}
2415
 
2416
 
2417
#-------------------------------------------------------------------------------
2418
# Function        : LinkEntry
2419
#
6504 dpurdie 2420
# Description     : Scan a package and locate platform specific directories
227 dpurdie 2421
#                   Create data structures to capture the information
6276 dpurdie 2422
#                   This function is used by LinkPkgArchive
227 dpurdie 2423
#                   to perfom the bulk of package inclusion work.
2424
#
6276 dpurdie 2425
# Inputs          : $platform   - Platform being processed
2426
#                   $entry      - Reference to a PackageEntry
227 dpurdie 2427
#
2428
sub LinkEntry
2429
{
6276 dpurdie 2430
    my( $platform, $base_entry ) = @_;
227 dpurdie 2431
 
2432
    #
6276 dpurdie 2433
    #   Clone the entry - we will add platform specific data into it
2434
    #
2435
    my $entry = dclone($base_entry);
227 dpurdie 2436
 
6276 dpurdie 2437
 
227 dpurdie 2438
    #   Populate includes:
2439
    #
2440
    #   - include/$platform                 (eg include/solaris)
2441
    #   - inc/$platform                     (eg inc/solaris)
2442
    #   - include.$platform                 (eg include.solaris)
2443
    #   - inc.$platform                     (eg inc.solaris)
2444
    #   - include                           (eg include)
2445
    #   - inc                               (eg inc)
2446
    #
2447
    #   plus, product specialisation directores
2448
    #
2449
    #   eg. BuildProduct( 'IDFC', 'WIN32' );
2450
    #
2451
    #   - inc/IDFC_WIN32                    <- derived platform
2452
    #   - inc/IDFC                          <- product
2453
    #   - inc/WIN32                         <- target
2454
    #..
2455
    my $parts = $BUILDINFO{$platform}{PARTS};
2456
 
2457
    foreach my $part ( @$parts )
2458
    {
6276 dpurdie 2459
        $entry->RuleInc( "/include." . $part );
2460
        $entry->RuleInc( "/inc." . $part );
2461
        $entry->RuleInc( "/include/" . $part );
227 dpurdie 2462
        $entry->RuleInc( "/inc/" . $part );
2463
    }
2464
 
2465
    #
2466
    #   Also search the root include directory - last
2467
    #
6276 dpurdie 2468
    $entry->RuleInc( "/include" );
227 dpurdie 2469
    $entry->RuleInc( "/inc" );
2470
 
2471
    #   Populate libraries:
2472
    #
2473
    #   - lib/lib.$platform[D|P]            (eg lib/lib.sparcD)
2474
    #   - lib/$platform[D|P]                (eg lib/lib.sparc)
2475
    #   - lib.$platform[D|P]                (eg lib.sparcD)
2476
    #
2477
    #   plus, product specialisation directores
2478
    #
2479
    #   eg. BuildProduct( 'IDFC', 'WIN32' );
2480
    #
2481
    #   - lib/IDFC_WIN32                    <- derived platform
2482
    #   - lib/IDFC                          <- product
2483
    #   - lib/WIN32                         <- target
2484
    #..
2485
    $parts = $BUILDINFO{$platform}{PARTS};
2486
 
2487
    foreach my $part ( @$parts )
2488
    {
6276 dpurdie 2489
        $entry->RuleLib("/lib" . ".$part" );
2490
        $entry->RuleLib("/lib" . "/lib.$part" );
227 dpurdie 2491
        $entry->RuleLib("/lib" . "/$part" );
2492
    }
2493
 
2494
    #
2495
    #   Some extra places to search
2496
    #   None. This is good as it indicates that all locations are described in PARTS
2497
    #
2498
    #   Do NOT search in /lib. There are no libraries that work on all platforms
2499
    #   Libraries are binaries!
2500
    #
2501
    #    $entry->RuleLib( "/lib" );
2502
 
2503
    #   Tools:
2504
    #
2505
    #   Tools provide an extensible search path for tools and
2506
    #   utilities used to build programs. These are tools that
2507
    #   are executable on the current host machine and are
2508
    #   independent of the toolset.
2509
    #
2510
    #..
2511
    $entry->ExamineToolPath();
2512
    $entry->ExamineThxPath($platform);
2513
    $entry->Cleanup();                          # cleanup tables
2514
 
2515
    #
2516
    #   Add the package entry to the array of such entries for
2517
    #   the current platform. Maintain the discovery order
2518
    #
2519
    #..
2520
    push ( @{$PKGRULES{$platform}}, $entry );
2521
}
2522
 
2523
 
2524
#-------------------------------------------------------------------------------
2525
# Function        : BuildPkgArchive
2526
#
2527
# Description     : Include an external package into the build sandbox
2528
#                   by copying the packages files into the interface directory
2529
#
2530
# Inputs          : package name
2531
#                   package version
2532
#
2533
sub BuildPkgArchive
2534
{
2535
    my( $name, $version ) = @_;
2536
 
2537
    return if ( $Clobber );                     # clobber mode ?
2538
 
2539
    Debug( "BuildPkgArchive:" );
2540
    Debug( "Name:      $name" );
2541
    Debug( "Version:   $version" );
2542
 
2543
    DataDirective("BuildPkgArchive");           # This directive allowed here
2544
 
2078 dpurdie 2545
    if ( $IgnorePkgs )
2546
    {
2547
        Log( "BuildPkgArchive . $name ($version) - Ignored" );
2548
        return;
2549
    }
2550
 
227 dpurdie 2551
    #
2552
    #   Ensure that we have do not have multiple definitions
2553
    #
2554
    if ( PackageEntry::Exists( $name, $version ) )
2555
    {
261 dpurdie 2556
        Log( "Duplicate Package: $name, $version. Duplicate entry ignored" );
227 dpurdie 2557
        return;
2558
    }
2559
 
2560
    if ( $Cache && $::GBE_DPKG_CACHE )
2561
    {
2562
        my $mode = ($Cache > 1) ? "-refresh" : "";
261 dpurdie 2563
        Log( "BuildPkgArchive . $name ($version) Update Cache" );
5744 dpurdie 2564
        System('--NoExit', "$::GBE_PERL $::GBE_TOOLS/cache_dpkg.pl $mode -wait -quiet $name/$version" );
227 dpurdie 2565
    }
2566
 
2567
    #
2568
    #   Locate the package
6133 dpurdie 2569
    #   Use the first instance of the package that is found
227 dpurdie 2570
    #
261 dpurdie 2571
    Log( "BuildPkgArchive . $name ($version)" );
6276 dpurdie 2572
    my ( $pkg, $local, $pkgSig ) = PackageLocate( $name, $version );
227 dpurdie 2573
    if ( $pkg )
2574
    {
2575
        #
2576
        #   Create a Package Entry
2577
        #
6276 dpurdie 2578
        my $entry = PackageEntry::New( $pkg, $name, $version, 'build', $local, $pkgSig );
227 dpurdie 2579
 
2580
        #
2581
        #   Determine if the package needs to be installed:
2582
        #       If the package is a 'local' package then force transfer
2583
        #       If the user has specified --cache then force transfer
2584
        #       If package is newer that copy, then force transfer
2585
        #       If copy does not exist, then force a transfer
2586
        #
6276 dpurdie 2587
        my $tag_dir = "$CwdFull/$BUILDINTERFACE/BuildTags";
227 dpurdie 2588
        my $tag_file = "$tag_dir/${name}_${version}.tag";
6073 dpurdie 2589
        my $arglist = GenerateInstallArgumentList();
227 dpurdie 2590
 
2591
        my $package_installed;
2592
        $package_installed = 1
2593
            if ( !$local &&
2594
                 !$Cache &&
6073 dpurdie 2595
                 !FileIsNewer( $entry->GetBaseDir('descpkg'), $tag_file ) &&
2596
                 TagFileMatch( $tag_file, $arglist)
2597
                  );
227 dpurdie 2598
 
2599
        #
2600
        #   Determine the package format and use the appropriate installer
2601
        #   Supported formats
6133 dpurdie 2602
        #       1) Package has a descpkg file (only style currently supported)
227 dpurdie 2603
        #
2604
        if ( $package_installed ) {
2605
            Verbose ("Package already installed: $name, $version");
2606
 
2607
        } else {
261 dpurdie 2608
            Log( "                . installing '$pkg'" );
2609
            Log( "                . -> " . readlink($pkg) ) if ( -l $pkg );
227 dpurdie 2610
 
2611
            if ( -e "$pkg/descpkg" )
2612
            {
2613
 
2614
                #
2615
                #   If forcing a BuildPkg, then don't use symlinks
2616
                #   to files in dpkg_archive
2617
                #
331 dpurdie 2618
                my @opts;
2619
                push @opts, "--NoSymlinks" if ( $ForceBuildPkg );
2620
                push @opts, "--AllowOverWrite" if ( $local );
227 dpurdie 2621
 
2622
                #
2623
                #   Determine all the Platforms, Products and Targets
2624
                #   that need to be installed
2625
                #
6073 dpurdie 2626
 
6276 dpurdie 2627
                System( "cd $pkg; $::GBE_PERL $::GBE_TOOLS/installpkg.pl $CwdFull/$BUILDINTERFACE $CwdFull @opts $arglist");
227 dpurdie 2628
                Error( "Package installation error" ) if ( $? != 0 );
2629
            }
2630
            else
2631
            {
2632
                Error ("Unknown package format for package $name/$version found in $pkg");
2633
            }
2634
 
2635
            #
2636
            #   Tag the package as installed - after it has been transferred
2637
            #
2638
            mkdir ( $tag_dir );
6073 dpurdie 2639
            FileCreate( $tag_file, $arglist );
227 dpurdie 2640
        }
2641
 
2642
        #
2643
        #   Process package
2644
        #
2645
        IncludePkg ( $name, $pkg );
2646
 
2647
        #
2648
        #   Complete the creation of the package entry
2649
        #   Add the information for all platforms
2650
        #
2651
        $entry->Cleanup();
2652
        for my $platform (@BUILD_ACTIVEPLATFORMS)
2653
        {
2654
            $entry->ExamineToolPath();
2655
            $entry->ExamineThxPath($platform);
2656
            push ( @{$PKGRULES{$platform}}, $entry );
2657
        }
2658
    }
2659
}
2660
 
2661
#-------------------------------------------------------------------------------
6684 dpurdie 2662
# Function        : LinkPkgExclude 
2663
#
2664
# Description     : Mark a package to be excluded / included for a specific build
2665
#                   Intended use:
2666
#                       Recover from really (reaaly) badly constructed packages
2667
#                       
2668
#                   Essentially this directive will 'Exclude' packages from the
2669
#                   a specific build target (platform) by removing it from data
2670
#                   structures that are exported to the make stage
2671
#                   
2672
#                   Process ONLY works for LinkPkgArchive packages
2673
#
2674
# Inputs          : platform-selector   - A JATS style platform specifier
2675
#                   package-list        - one or or packages to process
2676
#                   
2677
# Example         : LinkPkgExclude('!SK100', 'PulseSdk');
2678
#                   LinkPkgExclude('SK100' , 'crypto');
2679
#
2680
sub LinkPkgExclude
2681
{
2682
    DataDirective('LinkPkgExclude');
2683
    Error("LinkPkgExclude(@_) requires at least two arguments") unless ((scalar @_) >= 2);
2684
    #
2685
    #   Simply save the arguments for later processing
2686
    #
2687
    push @LINKPKGEXLUDES, join($;, @_);
2688
}
2689
 
2690
#-------------------------------------------------------------------------------
2691
# Function        : ProcessLinkPkgExclude 
2692
#
2693
# Description     : INTERNAL Function
2694
#                   Process the data collected by the LinkPkgExclude directives  
2695
#
2696
# Inputs          : None
2697
#                   Uses: LINKPKGEXLUDES    
2698
#
2699
# Returns         : Will modify interal classes and data structures
2700
#
2701
sub ProcessLinkPkgExclude
2702
{
2703
    my @unknownPlatforms;
2704
    my @unknownPkg;
2705
    my @notLinkPkg;
2706
 
2707
    #
2708
    #   Create a hash of known platforms - detect and report bad user input
2709
    #
2710
    my %fullPlatformList =  map { $_ => 1 } @BUILDPLATFORMS;
2711
 
2712
    #
2713
    #   Process each directive
2714
    #
2715
    foreach ( @LINKPKGEXLUDES )
2716
    {
2717
        my (@add, @remove);
2718
        my ($pSel, @pkgList) = split($;, $_);
2719
        Log("LinkPkgExclude $pSel, @pkgList");
2720
 
2721
 
2722
        #
2723
        #   Process the selector in the same manor as makefiles
2724
        #       Need the selector to be active
2725
        #       Selector may be an alias or a platform
2726
        #       Selector may be negated
2727
        #       Selectors are comma seperated
2728
        #       Additive elements are processed before subtactive elements
2729
        #           
2730
        my @pItems = split(/\s*,\s*/, $pSel);
2731
        @pItems = ExpandPlatforms( @pItems );
2732
 
2733
         foreach my $platform ( @pItems) {
2734
             my $pname = $platform;
2735
             my $invert;
2736
 
2737
             if (substr($platform, 0, 1) eq '!') {
2738
                 $invert = 1;
2739
                 $pname = substr($platform, 1)
2740
                 }
2741
 
2742
             unless (exists($fullPlatformList{$pname})) {
2743
                 UniquePush(\@unknownPlatforms, $pname);
2744
                 next;
2745
                 }
2746
 
2747
             if ( $invert )  {
2748
                 push @remove, $pname; 
2749
             } else {
2750
                 push @add, $pname; 
2751
             }
2752
         }
2753
 
2754
         #
2755
         #   Build complete list of allowed platforms
2756
         #       Process additive rules before removal rules
2757
         #       If there are no additive rules, then assume all protaforms
2758
         #
2759
         my %calcList;
2760
         @add = @BUILDPLATFORMS unless @add;
2761
         $calcList{uc $_} = 1 foreach (@add);
2762
         delete $calcList{uc $_} foreach (@remove);
2763
         Verbose2("LinkPkgExclude ", keys %calcList,",", @pkgList);
2764
 
2765
         #
2766
         #  Now have a list of platforms to process (exclude)
2767
         #  Now have a list of packages to exclude
2768
         #
2769
         #  Iterate over the package rules and mark those to be excluded
2770
         #
2771
         foreach my $platform ( keys %calcList )
2772
         {
2773
             unless (exists($PKGRULES{$platform})) {
2774
                 next;
2775
             }
2776
 
2777
             foreach my $ePackage (@pkgList) {
2778
                 my $pkgFound;
2779
                 foreach my $package ( @{$PKGRULES{$platform}} )
2780
                 {
2781
                     my $fname = $package->{'dname'};
2782
                     if ( $package->{'dproj'}) {
2783
                         $fname .= '.' . $package->{'dproj'};
2784
                     }
2785
 
2786
                     if ( $ePackage eq $package->{'dname'}  || $ePackage eq $fname) {
2787
                         $pkgFound = 1;
2788
 
2789
                         if ($package->{'type'} ne 'link') {
2790
                             UniquePush(\@notLinkPkg, $ePackage);
2791
                             last;
2792
                         }
2793
 
2794
                         $package->{'EXCLUDE'} = 1;
2795
                         Debug("Exclude", $platform, $fname );
2796
                         last;
2797
                     }
2798
                 }
2799
                 UniquePush(\@unknownPkg, $ePackage) unless $pkgFound;
2800
             }
2801
         }
2802
   }
2803
 
2804
    ReportError("LinkPkgExclude. Unknown platforms:", @unknownPlatforms) if @unknownPlatforms;
2805
    ReportError("LinkPkgExclude. Unknown packages:", @unknownPkg) if @unknownPkg;
2806
    ReportError("LinkPkgExclude. BuildPkgArchive not allowed for:", @notLinkPkg) if @notLinkPkg;
2807
    ErrorDoExit();
2808
}
2809
 
2810
#-------------------------------------------------------------------------------
311 dpurdie 2811
# Function        : CreateInterfacePackage
2812
#
2813
# Description     : Create a dummy package entry to describe the Interface
2814
#                   This is done AFTER all the BuildPkgArchive directives have
2815
#                   been processed so that the interface directory is fully
2816
#                   processed
2817
#
2818
# Inputs          : None
2819
#
2820
# Returns         : 
2821
#
2822
sub CreateInterfacePackage
2823
{
2824
    foreach my $platform ( @BUILD_ACTIVEPLATFORMS )
2825
    {
6276 dpurdie 2826
        my $entry = PackageEntry::Interface( "$CwdFull/$BUILDINTERFACE" );
311 dpurdie 2827
 
2828
        #
2829
        #   Locate include and lib bits within the interface
2830
        #   This is much simpler than for a LinkPkgArchive as the form
2831
        #   has been sanitized
2832
        #
2833
        my $parts = $BUILDINFO{$platform}{PARTS};
2834
 
2835
        foreach my $part ( @$parts )
2836
        {
2837
            $entry->RuleInc( "/include/" . $part );
2838
        }
2839
        $entry->RuleInc( "/include" );
2840
 
2841
        foreach my $part ( @$parts )
2842
        {
2843
            $entry->RuleLib("/lib/" . $part );
2844
        }
2845
 
2846
        $entry->ExamineToolPath();
2847
        $entry->ExamineThxPath($platform);
2848
        $entry->Cleanup();
2849
 
2850
        #
2851
        #   Add the package entry to the array of such entries for
2852
        #   the current platform. Force it to be the first one as
2853
        #   the interface directory will be scanned first
2854
        #
2855
        unshift ( @{$PKGRULES{$platform}}, $entry );
2856
    }
2857
}
2858
 
2859
#-------------------------------------------------------------------------------
227 dpurdie 2860
# Function        : GenerateInstallArgumentList
2861
#
2862
# Description     : Generate an argument list for the installpkg.pl script
2863
#                   The argument list is of the form
2864
#                       --Platform:xx[:xx[:xx]] --Platform:yy[:yy[:yy]] ...
2865
#                   Where xx is:
2866
#                       * a 'part' of the target platform
2867
#                         Order is: platform, product, ...  target( in that order )
2868
#                       * --Option[=yyy]
2869
#                        An option to be passed to the script. These are bound only
2870
#                        to the enclosed platform.
2871
# Inputs          :
2872
#
2873
# Returns         : See above
2874
#
2875
sub GenerateInstallArgumentList
2876
{
2877
    my @arglist;
2878
 
2879
    #
2880
    #   Generate the argument list as an array
2881
    #
2882
    for (@BUILD_ACTIVEPLATFORMS)
2883
    {
2884
        my @args = '--Platform';
2885
        push @args, @{$BUILDINFO{$_}{PARTS}};
2886
        push @arglist, join (":" , @args );
2887
    }
2888
 
2889
    return "@arglist";
2890
}
2891
 
2892
#-------------------------------------------------------------------------------
2893
# Function        : GeneratePlatformList
2894
#
2895
# Description     : Return a list of platforms that should particiate in this
2896
#                   build. This is a function of
2897
#                       1) Platforms defined in the build.pl file
5679 dpurdie 2898
#                       2) Platforms excluded in the build.pl file
2899
#                       3) User filter defined in GBE_BUILDFILTER
227 dpurdie 2900
#
2901
#                   The primary use of this function is to limit the creation
2902
#                   of makefiles to those that have supported compilers on
2903
#                   the underlying machine.
2904
#
2905
#                   GBE_BUILDFILTER is a space seperated string of words
2906
#                   Each word may be one of
2907
#                       OPTION=TAG or OPTION=!TAG
2908
#                       TAG or !TAG. This is the same as --TARGET=TAG
2909
#
2910
#                   Bare tags are taken to be TARGETS.
2911
#
2912
#                   Where OPTION may be one of
2913
#                       --PLATFORM
2914
#                       --PRODUCT
2915
#                       --TARGET
5679 dpurdie 2916
#                   For a BuildProduct( AA,BB,CC)
2917
#                       Product     - AA
2918
#                       Targets     - BB, CC
2919
#                       Platforms   - AA_BB, AA_CC
227 dpurdie 2920
#
2921
#                   Special cases
2922
#                   1) If GBE_BUILDFILTER is empty, then all available platforms are used
2923
#                      The global $All is set, then all available platforms are used
2924
#                   2) If the first word of GBE_BUILDFILTER is a negative filter,
2925
#                      ie is used the !xxxx or yyy=!xxxx construct, then it is assumed
2926
#                      that the filter will start with all available platforms
2927
#                   3) The special word --ALL forces selection of ALL platforms
2928
#                      and may reset any existing scanning
2929
#                   4) GBE_BUILDFILTER is parsed left to right. It is possible to add and
2930
#                      subtract items from the list.
2931
#                   5) OPTIONS are case insensitive
2932
#                      TAGS are case sensitive
2933
#
2934
#
2935
# Inputs          : GBE_BUILDFILTER from the environment
2936
#
2937
# Returns         : An array of platforms to include in the build
2938
#                   Maintains @BUILD_ACTIVEPLATFORMS  - the last calculated result
2939
#                   Ensures that @DEFBUILDPLATFORMS is a subset of @BUILD_ACTIVEPLATFORMS
6276 dpurdie 2940
#                   Rebuilds BUILDPLATFORMS to ensure that excluded platforms are not present
227 dpurdie 2941
#
2942
sub GeneratePlatformList
2943
{
2944
    #
2945
    #   Return the cached result for speed
2946
    #   The value need only be calculated once
2947
    #
2931 dpurdie 2948
    unless ( @BUILD_ACTIVEPLATFORMS )
227 dpurdie 2949
    {
2950
        my ($platform_filter);
2951
        my %result;
2952
        my %part_to_platform;
6276 dpurdie 2953
        my @New_BUILDPLATFORMS = ();
227 dpurdie 2954
 
2955
        #
2956
        #   Create a data structure to assist in the production of the platform list
2957
        #   The structure will be a hash of hashes of arrays
2958
        #
2959
        #   The first level hash will be keyed by the word TARGET, PRODUCT or PLATFORM
2960
        #   The second level of the hash will keyed by available targets, products or platforms
2961
        #   The value of the field will be an array of platforms that match the keyword
2962
        #
2963
        for my $platform (keys (%::BUILDINFO))
2964
        {
2965
            my $pParts = $::BUILDINFO{$platform};
2966
 
2967
            #
6276 dpurdie 2968
            #   Include into New_BUILDPLATFORMS 
2969
            #
2970
            if ($pParts->{NOT_AVAILABLE} <= 1) {
2971
                push @New_BUILDPLATFORMS, $platform;
2972
            }
2973
 
2974
            #
227 dpurdie 2975
            #   Skip platforms that are known to be unavailable on this build
2976
            #   machine. Self configure
2977
            #
2978
            next if ( $pParts->{NOT_AVAILABLE} );
2979
 
2980
            my $target  = $pParts->{TARGET};
2981
            my $product = $pParts->{PRODUCT};
2982
 
2983
            push @{$part_to_platform{'PLATFORM'}{$platform}}, $platform;
2984
            push @{$part_to_platform{'TARGET'}  {$target}}  , $platform;
2985
            push @{$part_to_platform{'PRODUCT'} {$product}} , $platform;
2986
        }
2987
        #
2988
        #   Determine the source of the filter
2989
        #   If the user provides one, then use it.
2990
        #   Otherwise its taken from the environment.
2991
        #
2992
        #   Global build all platforms - Kill any user filter
2993
        #
2994
        if ( $All )
2995
        {
2996
            $platform_filter = "";
2997
        }
2998
        else
2999
        {
3000
            $platform_filter = "";
6276 dpurdie 3001
            $platform_filter = uc $::GBE_BUILDFILTER
227 dpurdie 3002
                if ( defined($::GBE_BUILDFILTER) );
3003
        }
3004
        Debug( "GeneratePlatformList: Filter:$platform_filter" );
3005
 
3006
        #
3007
        #   Detect the special cases
5679 dpurdie 3008
        #       1) No user definition
227 dpurdie 3009
        #       2) First word contains a subtractive element
5679 dpurdie 3010
        #   And assume all platforms    
227 dpurdie 3011
        #
3012
        my (@filter) = split( ' ', $platform_filter );
3013
 
3014
        if ( !scalar @filter || $filter[0] =~ m/^$/ || $filter[0] =~ m/!/ )
3015
        {
3016
            %result = %{$part_to_platform{'PLATFORM'}}
3017
                if exists $part_to_platform{'PLATFORM'} ;
3018
        }
5679 dpurdie 3019
 
6276 dpurdie 3020
        #
3021
        # Add GENERIC platforms to the platform filter, if available
3022
        #
3023
        if (exists $part_to_platform{'PLATFORM'})
3024
        {
3025
            foreach my $platform( 'GENERIC', 'GENERIC_' . uc($::GBE_MACHTYPE) )
3026
            {
3027
                $result{$platform} = 1 if (exists $part_to_platform{'PLATFORM'}{$platform}) 
3028
            }
3029
        }
3030
 
227 dpurdie 3031
#DebugDumpData( "PartToPlatform", \%part_to_platform );
6276 dpurdie 3032
#DebugDumpData("Result", \%result);
227 dpurdie 3033
 
3034
        #
3035
        #   Process each element in the user filter list
3036
        #   Expand platforms into known aliases
3037
        #
3038
        for my $word (@filter)
3039
        {
3040
            my $platform;
3041
 
3042
            if ( $word =~ m/^--ALL/i )
3043
            {
3044
                %result = %{$part_to_platform{'PLATFORM'}};
3045
            }
3046
            elsif ( $word =~ m/^--(TARGET)=(!?)(.*)/i ||
3047
                    $word =~ m/^--(PRODUCT)=(!?)(.*)/i ||
3048
                    $word =~ m/^--(PLATFORM)=(!?)(.*)/i ||
3049
                    ( $word !~ m/^-/ && $word =~ m/()(!?)(.*)/ )
3050
                )
3051
            {
3052
                my $table = uc($1);
3053
                $table = "TARGET"
3054
                    unless ( $1 );
3055
 
3056
                #
3057
                #   Expand PLATFORMs into known aliases
3058
                #   Alias will expand to PLATFORMs so it won't work unless we are
6133 dpurdie 3059
                #   processing PLATFORMs.
227 dpurdie 3060
                #
3061
                my @taglist = ( $table eq "PLATFORM" ) ? ExpandPlatforms($3) : $3;
3062
 
3063
                #
3064
                #   Add / Remove items from the result
3065
                #
3066
                for my $item ( @taglist )
3067
                {
3068
                    my $plist = $part_to_platform{$table}{$item};
3069
                    for ( @{$plist})
3070
                    {
6133 dpurdie 3071
                        if ( $2 ) {
227 dpurdie 3072
                            delete $result{$_};
6133 dpurdie 3073
                        } else {
227 dpurdie 3074
                            $result{$_} = 1;
3075
                        }
3076
                    }
3077
                }
3078
            }
3079
            else
3080
            {
3081
                print "GBE_BUILDFILTER filter term not understood: $word\n";
3082
            }
3083
        }
3084
 
3085
        #
3086
        #   Return an array of platforms to process
3087
        #
3088
        @BUILD_ACTIVEPLATFORMS = sort keys %result;
3089
 
3090
        #
3091
        #   Ensure that DEFBUILDPLATFORMS is a subset of build active platforms
3092
        #
3093
        my @NEW_DEFBUILDPLATFORMS;
3094
        foreach ( @DEFBUILDPLATFORMS )
3095
        {
3096
            push @NEW_DEFBUILDPLATFORMS, $_
3097
                if ( exists $result{$_} );
3098
        }
3099
        @DEFBUILDPLATFORMS = @NEW_DEFBUILDPLATFORMS;
6276 dpurdie 3100
 
3101
        #
3102
        #   Update BUILDPLATFORMS
3103
        #
3104
        @BUILDPLATFORMS = @New_BUILDPLATFORMS;
227 dpurdie 3105
    }
3106
 
3107
    Debug("GeneratePlatformList: Result:@BUILD_ACTIVEPLATFORMS");
3108
    return @BUILD_ACTIVEPLATFORMS;
3109
}
3110
 
3111
#-------------------------------------------------------------------------------
3112
# Function        : PrintPlatforms
3113
#
3114
# Description     : Petty print the specified platform list, breaking line
6276 dpurdie 3115
#                   on either a primary key change or length width >100.
227 dpurdie 3116
#
6276 dpurdie 3117
# Inputs          : $list           - Reference to an array
3118
#                   $nl             - New line stuff.
3119
#                                     Use to prefix new lines
227 dpurdie 3120
#
6276 dpurdie 3121
# Returns         : Formatted string
3122
#
227 dpurdie 3123
# Example Output :
3124
#
3125
#           DDU_LMOS_WIN32 DDU_LMOS_linux_armv4 DDU_LMOS_linux_i386
3126
#           IDFC_LMOS_WIN32 IDFC_LMOS_linux_armv4 IDFC_LMOS_linux_i386
3127
#           LMOS_WCEPSPC_ARM LMOS_WCEPSPC_EMU LMOS_WIN32 LMOS_linux_armv4
3128
#           LMOS_linux_i386
3129
#..
3130
sub PrintPlatforms
3131
{
3132
    my ($platforms, $nl) = @_;
6276 dpurdie 3133
    my ($string) = "";
3134
    my $maxLen = 100 - length($nl);
227 dpurdie 3135
 
2931 dpurdie 3136
    if ( @$platforms )
227 dpurdie 3137
    {
6276 dpurdie 3138
        my $line = "";
3139
        my $pel = "";
3140
        my $first = 1;
3141
        my $prefix = '';
3142
        foreach my $k ( sort @$platforms)
227 dpurdie 3143
        {
6276 dpurdie 3144
            my $k2 = substr($k, 0 , 2);
3145
            if (( $k2 ne $pel  || (length($line) + length ($k) > $maxLen) ) && (!$first)) {
3146
                $string .= $line;
3147
                $line = $nl;
3148
                $prefix = '';
227 dpurdie 3149
            }
6276 dpurdie 3150
            $line .= $prefix . $k;
3151
            $pel = $k2;
3152
            $first = 0;
3153
            $prefix = ' ';
227 dpurdie 3154
        }
6276 dpurdie 3155
        $string .= $line;
227 dpurdie 3156
    }
3157
    return $string;
3158
}
241 dpurdie 3159
#-------------------------------------------------------------------------------
3160
# Function        : PrintList
3161
#
3162
# Description     : Pretty format an array to fit within 80 char line
3163
#                   Perform wrapping as required
3164
#
3165
# Inputs          : $list           - Reference to an array
3166
#                   $nl             - New line stuff.
3167
#                                     Use to prefix new lines
3168
#
3169
# Returns         : string
3170
#
3171
sub PrintList
3172
{
6276 dpurdie 3173
    my ($platforms, $nl) = @_;
3174
    my ($string) = "";
3175
    my $maxLen = 100 - length($nl);
227 dpurdie 3176
 
6276 dpurdie 3177
    if ( @$platforms )
241 dpurdie 3178
    {
6276 dpurdie 3179
        my $line = "";
3180
        my $first = 1;
3181
        my $prefix = '';
3182
        foreach my $k ( sort @$platforms)
241 dpurdie 3183
        {
6276 dpurdie 3184
            if ((length($line) + length ($k) > $maxLen) && (!$first)) {
3185
                $string .= $line;
3186
                $line = $nl;
3187
                $prefix = '';
241 dpurdie 3188
            }
6276 dpurdie 3189
            $line .= $prefix . $k;
3190
            $first = 0;
3191
            $prefix = ' ';
241 dpurdie 3192
        }
6276 dpurdie 3193
        $string .= $line;
241 dpurdie 3194
    }
3195
    return $string;
3196
}
3197
 
305 dpurdie 3198
#-------------------------------------------------------------------------------
3199
# Function        : BuildReleaseFile
3200
#
3201
# Description     : Legacy function
3202
#                   Don't know what it was meant to do
3203
#                   Unfortunately it is present in a lot of build.pl files
3204
#
3205
#                   Not well supported on all machine types
3206
#
331 dpurdie 3207
# Inputs          : None that are used
305 dpurdie 3208
#
331 dpurdie 3209
# Returns         : Undefined
305 dpurdie 3210
#
227 dpurdie 3211
sub BuildReleaseFile
3212
{
6619 dpurdie 3213
    Warning("BuildReleaseFile directive does nothing and should be removed") unless $Clobber;
227 dpurdie 3214
}
3215
 
305 dpurdie 3216
#-------------------------------------------------------------------------------
3217
# Function        : BuildSnapshot
3218
#
3219
# Description     : Legacy function
3220
#                   Don't know what it was meant to do
3221
#                   Unfortunately it is present in a lot of build.pl files
3222
#
3223
# Inputs          : None that are used
3224
#
3225
# Returns         : Undefined
3226
#
227 dpurdie 3227
sub BuildSnapshot
3228
{
6619 dpurdie 3229
    Warning("BuildSnapshot directive does nothing and should be removed") unless $Clobber;
227 dpurdie 3230
}
3231
 
305 dpurdie 3232
#-------------------------------------------------------------------------------
3233
# Function        : BuildSrcArchive
3234
#
3235
# Description     : Create a source snapshot of the build source
3236
#                   Designed to provide a source image for packaging
3237
#                   examples
3238
#
3239
#                   Should be platform independent
3240
#
3241
#                   Creates an archive file and places it into the
3242
#                   interface directory. The archive will be packaged
3243
#                   automatically by the build process
3244
#
3245
#                   Use the 'pax' utility
3246
#                       1) Can massage the file path such that the stored
3247
#                          directory image contains the package name and version
3248
#
3249
#                   Directive can be used at any time before the BuildMake
3250
#
3251
#                   Will handle the existence of an auto.pl file by inserting
3252
#                   it as build.pl.
3253
#
6133 dpurdie 3254
# Inputs          : $platform   - In ABT mode. Process under this platform name
305 dpurdie 3255
#
3256
#
3257
# Returns         : 
3258
#
3259
sub BuildSrcArchive
3260
{
6133 dpurdie 3261
    my ($platform) = @_;
3262
    Error ("BuildSrcArchive requires one platform specifier") unless (defined $platform);
3263
 
3264
 
305 dpurdie 3265
    #
3266
    #   If we are clobbering, then there is nothing to do
3267
    #   The generated file is placed within the interface
3268
    #   directory and that directory will be deleted during the clobber
3269
    #
3270
    return if ( $Clobber );
3271
    DataDirective("BuildSrcArchive");
227 dpurdie 3272
 
305 dpurdie 3273
    #
6133 dpurdie 3274
    #   If not in ABT mode, then build archive on developers machine
3275
    #   In ABT mode only build the archive on a machine whose platform name is in the build filter
3276
    #
3277
    my $doBuild;
3278
    if (defined($::GBE_ABT))
3279
    {
3280
        if (defined ($::GBE_BUILDFILTER))
3281
        {
3282
            $doBuild  = grep( /^$platform/, split( ' ', $::GBE_BUILDFILTER ) );
3283
        }
3284
        unless ( $doBuild )
3285
        {
3286
            Log( "SrcPackage . Not on this machine" );
3287
            return; 
3288
        }
3289
    }
3290
 
3291
 
3292
    #
305 dpurdie 3293
    #   Currently this operation is only supported of some platforms
3294
    #   Only supported on Unix platforms
3295
    #   Uses the 'pax' utility
3296
    #
3297
    unless ( LocateProgInPath ( 'pax', '--All' ) && ( $ScmHost eq "Unix" ) )
3298
    {
3299
        Log( "SrcPackage . Not supported" );
3300
        return;
3301
    }
3302
 
3303
    #
3304
    #   Only allow one instance of the directive
3305
    #
3306
    Error ("Multiple BuildSrcArchive directives not supported")
3307
        if ( $build_source_pkg );
3308
 
3309
    #
3310
    #   Create the name of the archive
3311
    #       Based on the package name and version
3312
    #       Has no spaces
3313
    #
3314
    my $build_name = $BUILDNAME;
3315
    $build_name =~ s~\s+~_~g;
3316
 
3317
    #
3318
    #   Create the archive in the interface directory
3319
    #   Don't need to clobber it as the entire interface directory
3320
    #   will be clobbered
3321
    #
3322
    $build_source_pkg = $build_name;
3323
}
3324
 
3325
#-------------------------------------------------------------------------------
3326
# Function        : BuildSrcArchiveBody
227 dpurdie 3327
#
305 dpurdie 3328
# Description     : Function to implement the body of the BuildSrcArchive
3329
#                   operation. Will be invoked during BuildMake
3330
#
3331
# Inputs          : None
3332
#
3333
# Returns         : 
3334
#
3335
sub BuildSrcArchiveBody
3336
{
3337
    return unless ( $build_source_pkg );
3338
 
3339
    my $archive_dir = "pkg/$BUILDNAME_PACKAGE/src";
3340
    my $archive_file = "$build_source_pkg" . '.tar';
3341
 
3342
    Log( "SrcPackage . $archive_file.gz" );
3343
    unlink "$archive_dir/$archive_file";
3344
    unlink "$archive_dir/$archive_file.gz";
3345
    mkpath($archive_dir, 0, 0775);
3346
 
3347
    #
3348
    #   Create a list of files and top-level dirs to add to source archive
3349
    #   Many files are ignored
3350
    #   Should only be executed on the first 'build' thus many internal
3351
    #   directories will not be present
3352
    #
3353
    my @flist;
3354
    my $auto_pl;
3355
    opendir (my $tp, '.' ) or Error ("Cannot read current directory");
3356
    while ( $_ = readdir($tp) )
3357
    {
3358
        next if ( m/^\.$/ );
3359
        next if ( m'^\.\.$' );
3360
        next if ( m'^build\.log$' );
3361
        next if ( m'\.gbe$' );
6133 dpurdie 3362
        next if ( m'\.svn$' );
3363
        next if ( m'\.git$' );
3364
        next if ( m'\.cvs$' );
3365
        next if ( m'local_dpkg_archive$' );
3366
        next if ( m'\.jats.packageroot$' );
305 dpurdie 3367
        next if ( m'^local$' );
3368
        next if ( m'^pkg$' );
3369
        next if ( m/^$BUILDINTERFACE$/ );
3370
        $auto_pl = 1, next  if ( m'^auto\.pl$' );
3371
        next if (  m'^build\.pl$' );
3372
        next if ( m/^$build_source_pkg$/ );
3373
        push @flist, $_;
3374
    }
3375
    closedir $tp;
3376
 
3377
    #
3378
    #   If we don't have an auto.pl, then we add the build.pl file
3379
    #   If we do have a auto.pl - it gets tricky. Its don't after the
3380
    #   initial pax command
3381
    #
3382
    unless ( $auto_pl )
3383
    {
3384
        push @flist, 'build.pl';
3385
    }
3386
 
3387
    #
3388
    #   Create the command to be executed
3389
    #   Prefix archive paths with build_name
3390
    #
3391
    my @command = ( 'pax', '-w', '-f', "$archive_dir/$archive_file" );
3392
    System( '--NoShell' , @command, '-s', "~^~$build_source_pkg/~", @flist );
3393
 
3394
    #
3395
    #   If we have an auto.pl file, then we need to add it to the archive
3396
    #   but it needs to be called build.pl
3397
    #
3398
    if ( $auto_pl )
3399
    {
3400
        System( '--NoShell' , @command, '-a', '-s', "~^auto.pl~$build_source_pkg/build.pl~" , 'auto.pl' );
3401
    }
3402
 
3403
    #
3404
    #   Must now zip the file
3405
    #   Can't zip and append at the same time
3406
    #
3407
    System( '--NoShell' , 'gzip', "$archive_dir/$archive_file" );
3408
 
3409
    #
3410
    #   Display the results
3411
    #
3412
    System ('--NoShell', 'pax', '-z', "-f$archive_dir/$archive_file.gz")
3413
        if (IsVerbose (1));
3414
}
3415
 
3416
#-------------------------------------------------------------------------------
3417
# Function        : BuildAccessPerms
3418
#
3419
# Description     : Check if access/permissions setting requested...
3420
#                   Legacy
3421
#
331 dpurdie 3422
#                   Don't know what it was meant to do
3423
#                   Unfortunately it is present in a lot of build.pl files
305 dpurdie 3424
#
331 dpurdie 3425
# Inputs          : None that are used
305 dpurdie 3426
#
331 dpurdie 3427
# Returns         : Undefined
3428
#
227 dpurdie 3429
sub BuildAccessPerms
3430
{
6619 dpurdie 3431
    Warning("BuildAccessPerms directive does nothing and should be removed") unless $Clobber;
227 dpurdie 3432
}
3433
 
3434
 
3435
sub BuildSetenv
3436
{
6619 dpurdie 3437
    Warning("BuildSetenv directive does nothing and should be removed") unless $Clobber;
227 dpurdie 3438
    push( @BUILDSETENV, @_ );
3439
}
3440
 
3441
#-------------------------------------------------------------------------------
3442
# Function        : DataDirective
3443
#
3444
# Description     : Called by data collection directives to ensure that we are
3445
#                   still collecting data and that we have collected other data
3446
#
3447
# Inputs          : $dname              - Directive Name
3448
#
3449
# Returns         : Will error if we are not
3450
#
3451
sub DataDirective
3452
{
3453
    my ($dname) = @_;
3454
 
3455
    Error( "$dname() must appear after BuildName()...")
3456
        if ( $BUILDNAME eq "" );
3457
 
3458
    Error( "$dname() must appear after BuildInterface()...")
3459
        unless( $BUILDINTERFACE );
3460
 
3461
    Error( "$dname() not allowed after BuildDescpkg, BuildIncpkg, BuildVersion or BuildMake")
3462
        if( $BUILDPHASE);
3463
}
3464
 
3465
#-------------------------------------------------------------------------------
3466
# Function        : StartBuildPhase
3467
#
3468
# Description     : Called by directives that deal with the building phases
3469
#                   to perform common initialisation and to ensure that
3470
#                   directives that collect data are no longer called
3471
#
305 dpurdie 3472
# Inputs          : last                - True: Last directive expected
227 dpurdie 3473
#
3474
# Returns         : May generate an error
3475
#
3476
sub StartBuildPhase
3477
{
305 dpurdie 3478
    my ($last) = @_;
3479
 
227 dpurdie 3480
    #
305 dpurdie 3481
    #   Ensure directive is allowed
3482
    #       $BUILDPHASE >  1     - No more directives allowed
3483
    #       $BUILDPHASE == 1     - Allowed directive
3484
    #
3485
    if ( $BUILDPHASE > 1 )
3486
    {
3487
        my $function = (caller(1))[3];
3488
        $function =~ s~.*::~~;
3489
        Error ("Directive not allowed: $function","'BuildMake' must be the last directive in the build file");
3490
    }
3491
 
3492
    #
227 dpurdie 3493
    #   Only do it once
3494
    #
305 dpurdie 3495
    return if ( $BUILDPHASE  );
3496
    $BUILDPHASE = 1;
227 dpurdie 3497
 
3498
    #
341 dpurdie 3499
    #   If we are not performing a ForceBuild, then we don't need to continue
3500
    #   We have updated the interface directory with BuildPkgArchive
3501
    #   information.
3502
    #
3503
    TestForForcedBuild();
3504
 
3505
    #
6133 dpurdie 3506
    #   Calculate the aliases that are being extracted from targets
227 dpurdie 3507
    #
3508
    Process_TargetAlias();
3509
 
3510
    #
6198 dpurdie 3511
    #   Calculate defined aliases
6133 dpurdie 3512
    #       Limit the Aliases to active platforms
6198 dpurdie 3513
    #       ie: NATIVE INSTRUMENT PKG_WIN PKG_RPM PKG_DEB SK
4728 dpurdie 3514
    #
6276 dpurdie 3515
    my %activePlatformMap;
3516
    foreach my $item ( keys %BUILDINFO) {
3517
           my $pInfo = $BUILDINFO{$item};
3518
           next if $pInfo->{NOT_AVAILABLE} > 1; 
3519
           push @{$activePlatformMap{$pInfo->{TARGET}}}, $item;
3520
    }
3521
 
6198 dpurdie 3522
    foreach my $alias ( @PlatformConfig::BuildAliases )
4728 dpurdie 3523
    {
6276 dpurdie 3524
        if (exists $BUILDALIAS{$alias})  
4728 dpurdie 3525
        {
6198 dpurdie 3526
            # Will occur if GBE_ABT has been set, for backward compatibility
6133 dpurdie 3527
            Warning("User has manually specified a $alias alias",'Default alias will not be set.');
6276 dpurdie 3528
            #DebugDumpData("BUILDALIAS", \%BUILDALIAS);
4728 dpurdie 3529
        }
6133 dpurdie 3530
        else
3531
        {
6276 dpurdie 3532
            my @activeAliases;
3533
            foreach my $item (PlatformConfig::getTargetsByTag($alias)) {
3534
                if (exists($activePlatformMap{$item})) {
3535
                    push (@activeAliases, @{$activePlatformMap{$item}});
6177 dpurdie 3536
                }
3537
            }
6276 dpurdie 3538
 
6133 dpurdie 3539
            $BUILDALIAS{$alias} = join(' ', @activeAliases) if (@activeAliases);
3540
 
3541
            #
3542
            #   Add to the build entry too
3543
            #
6276 dpurdie 3544
            foreach my $aliasTarget (@activeAliases) {
6133 dpurdie 3545
                push @{$BUILDINFO{$aliasTarget}{USERALIAS}}, $alias;
3546
            }
3547
        }
4728 dpurdie 3548
    }
6133 dpurdie 3549
    CleanUp_Aliases();
6276 dpurdie 3550
    ProcessBuildArgument();
6684 dpurdie 3551
    ProcessLinkPkgExclude();
4728 dpurdie 3552
 
3553
    #
311 dpurdie 3554
    #   Create dummy package to describe the Interface directory
3555
    #
3556
    CreateInterfacePackage();
3557
 
3558
    #
227 dpurdie 3559
    #   Sanity test the users packages
6133 dpurdie 3560
    #       In a sandbox all bet are off
227 dpurdie 3561
    #
6133 dpurdie 3562
    PackageEntry::SanityTest() unless ($Clobber || $::GBE_SANDBOX);
227 dpurdie 3563
 
3564
    #
3565
    #   Validate the $Srcdir before its first real use
3566
    #   This is calculated from the user directives
3567
    #
3568
 
3569
    #.. Determine default "source" root
3570
    #
3571
    if ( $Srcdir eq "" )
3572
    {
3573
        Warning( "Both the directories 'src' and 'SRC' exist ....." )
3574
            if ( $ScmHost eq "Unix" && -e "src" && -e "SRC" );
3575
 
3576
        if ( -e "src" ) {
3577
            $Srcdir = "src";
3578
        } else {
3579
            ( -e "SRC" ) ||
3580
                Error( "Neither the directory 'src' nor 'SRC' exist ....." );
3581
            $Srcdir = "SRC";
3582
        }
3583
    }
3584
 
3585
    #
3586
    #   Must have a valid Srcdir
3587
    #
3588
    Error ("Source directory not found: $Srcdir")
3589
        unless ( $Srcdir && -d $Srcdir );
3590
 
305 dpurdie 3591
    #
3592
    #   Create source package
3593
    #
3594
    BuildSrcArchiveBody();
3595
 
227 dpurdie 3596
    return $Srcdir;
3597
}
3598
 
3599
#-------------------------------------------------------------------------------
341 dpurdie 3600
# Function        : TestForForcedBuild
3601
#
3602
# Description     : If a non-forced build has been requested, then see
3603
#                   if a build is required ( ie: build.pl modified )
6133 dpurdie 3604
#                   
3605
#                   Check:
3606
#                       Time stamp of build.pl
3607
#                       Time stamp of Makefile.gbe
3608
#                       BuildFilter has not changed
3609
#                       Signature of dependencies has not changed
3610
#                       No packages consumed from within the sandbox
341 dpurdie 3611
#
3612
# Inputs          : None
3613
#
3614
# Returns         : May not return
6133 dpurdie 3615
#                   Will return if we need to perform a build
341 dpurdie 3616
#
3617
sub TestForForcedBuild
3618
{
3619
    #
3620
    #   Always return if in clobber mode
3621
    #
3622
    return if ( $Clobber );
3623
 
3624
    if ( ! $ForceBuild  )
3625
    {
3626
        my @build_warn;
6276 dpurdie 3627
        my $bstamp = -M "$CwdFull/$ScmBuildSrc";
3628
        my $tstamp = -M "$CwdFull/Makefile.gbe";
341 dpurdie 3629
 
3630
        push @build_warn, "Missing: Makefile.gbe" unless ( defined $tstamp );
3631
        push @build_warn, "Modified build file ($ScmBuildSrc)" if ( $tstamp && $bstamp < $tstamp );
3632
 
363 dpurdie 3633
        #
3634
        #   Ensure that the build filter has not changed
3635
        #   If the user has changed the buildfilter, then we need to
3636
        #   force a build.
3637
        #
6133 dpurdie 3638
        #   The root Makefile.gbe will have a $ScmBuildFilter entry
363 dpurdie 3639
        #
3640
        unless ( @build_warn )
3641
        {
3642
            use JatsMakeInfo;
3643
            ReadMakeInfo();
5726 dpurdie 3644
            my $line = $::ScmBuildFilter || '';
3645
            $line =~ s~\s+~ ~g;
363 dpurdie 3646
 
5726 dpurdie 3647
            my $filter = $::GBE_BUILDFILTER || '';
3648
            $filter =~ s~\s+~ ~g;
3649
            if ( $line ne $filter )
3650
            {
3651
                push @build_warn, "Build filter has changed";
3652
                Verbose2 ("Buildfilter Test: Was:$line, Is:$::GBE_BUILDFILTER");
3653
            }
363 dpurdie 3654
        }
3655
 
6133 dpurdie 3656
        #
3657
        #   If any of the imported packages are from a sandbox, then we must force a build
3658
        #   and a make.
3659
        #
3660
        if ($pkgFromSandbox)
3661
        {
3662
            push @build_warn, "Consuming packages from within the sandbox";
3663
        }
3664
 
341 dpurdie 3665
        if ( @build_warn )
3666
        {
363 dpurdie 3667
            Verbose ("Forcing Build.", @build_warn );
341 dpurdie 3668
        }
3669
        else
3670
        {
3671
            Verbose ("No build performed. Build files up to date");
3672
            Log ("Build files up to date") if $::GBE_SANDBOX;
3673
            exit 0;
3674
        }
3675
    }
3676
}
3677
 
3678
#-------------------------------------------------------------------------------
305 dpurdie 3679
# Function        : LastBuildDirective
3680
#
3681
# Description     : No more build directives allowed
3682
#
3683
# Inputs          : 
3684
#
3685
# Returns         : 
3686
#
3687
sub LastBuildDirective
3688
{
3689
    $BUILDPHASE = 2;
3690
}
3691
 
3692
#-------------------------------------------------------------------------------
227 dpurdie 3693
# Function        : BuildPackageLink
3694
#
3695
# Description     : Create a soft link from sandbox_dpkg_archive to the package
3696
#                   being created by this build
3697
#
3698
#                   For backward compatability.
3699
#                   If GBE_DPKG_SBOX is not defined, then use GBE_DPKG_LOCAL
3700
#
3701
#                   This will allow multiple components to work together
3702
#
3703
#                   Note: When called in Clobber-mode the link will be deleted
3704
#
3705
# Inputs          : $BUILDNAME              - The package name
3706
#                   $BUILDNAME_PROJECT      - Project extension
3707
#                   $::GBE_DPKG_SBOX        - Path of sandbox_dpkg_archive
3708
#                   $::GBE_DPKG_LOCAL       - Path of local_dpkg_archive
3709
#                   $::GBE_DPKG             - Main repository
3710
#
3711
# Returns         : Nothing
3712
#
3713
sub BuildPackageLink
3714
{
3715
    my $target_archive;
3716
    my $target_archive_name;
3717
    my $link_file;
3718
    my $tag;
371 dpurdie 3719
    my $root_path;
227 dpurdie 3720
 
3721
    #
6276 dpurdie 3722
    #   In the build system we do NOT want to consume packages from within the sandbox
3723
    #   because they may be partially formed. They need to be consumed from a published
3724
    #   archive.
3725
    #   
3726
    #   If we are in an ABT sandbox, then don't create a link file
3727
    #   
3728
    return if (defined($::GBE_ABT));
3729
 
3730
    #
227 dpurdie 3731
    #   Determine the path (and name) of the target archive
3732
    #   Use sandbox_dpkg_archive if it exists
3733
    #   Use local_dpkg_acrhive for backward compatability (should be removed after JATS 2.64.2+)
3734
    #
3735
    if ( $target_archive = $::GBE_DPKG_SBOX )
3736
    {
3737
        $target_archive_name = "sandbox_dpkg_archive";
3738
        $tag = "Sandbox";
359 dpurdie 3739
        if ( $sandbox_exact )
3740
        {
3741
            $link_file = "$BUILDVERSION.lnk";
3742
        }
3743
        else
3744
        {
3745
            $link_file  = 'sandbox' . ${BUILDNAME_SUFFIX} . '.lnk';
3746
        }
6276 dpurdie 3747
        $root_path = 'GBE_SANDBOX' . substr($CwdFull, length($::GBE_SANDBOX));
371 dpurdie 3748
        Verbose2("Root Path: $::GBE_SANDBOX, $root_path");
227 dpurdie 3749
    }
3750
    elsif ( $target_archive = $::GBE_DPKG_LOCAL )
3751
    {
3752
        $target_archive_name = "local_dpkg_archive";
3753
        $link_file = "$BUILDVERSION.lnk";
3754
        $tag = "Local";
6276 dpurdie 3755
        $root_path = $CwdFull;
227 dpurdie 3756
    }
3757
    else
3758
    {
3759
        Verbose("Cannot locate local or sandbox archive")
3760
            unless $Clobber;
3761
        return;
3762
    }
3763
 
3764
    #
3765
    #   Santity test
3766
    #   Target must be a directory
3767
    #
3768
    unless ( -d $target_archive )
3769
    {
241 dpurdie 3770
        Warning("$target_archive_name is not a directory: $target_archive")
227 dpurdie 3771
            unless $Clobber;
3772
        return;
3773
    }
3774
 
3775
    my $link_dir = "$target_archive/$BUILDNAME_PACKAGE";
3776
    my $link_path = "$link_dir/$link_file";
3777
 
6133 dpurdie 3778
    if ( $Clobber || $NoBuild )
227 dpurdie 3779
    {
3780
        unlink $link_path;          # Delete the link
3781
        rmdir $link_dir;            # Delete only if empty
3782
    }
3783
    else
3784
    {
261 dpurdie 3785
        Log( "Local Link . $BUILDNAME_PACKAGE/$link_file ($tag)");
3786
        mkdir $link_dir unless -d $link_dir;
371 dpurdie 3787
        FileCreate ( $link_path, "$root_path/pkg/$BUILDNAME_PACKAGE");
227 dpurdie 3788
    }
3789
}
3790
 
3791
#-------------------------------------------------------------------------------
7452 dpurdie 3792
# Function        : genSandboxFile 
3793
#
3794
# Description     : Generate the base part of a sandbox file name 
3795
#
3796
# Inputs          : $pkgName
3797
#                   $pkgVersion
3798
#                   $pkgSuffix
3799
#
3800
# Returns         : Base part of a sandbox file name
3801
#                       Undef if not in a sandbox
3802
#
3803
sub genSandboxFile
3804
{
3805
    my ($pkgName, $pkgVersion, $pkgSuffix) = @_;
3806
 
3807
    my $sandbox_dpkg_archive = $::GBE_DPKG_SBOX;
3808
    return unless ( $sandbox_dpkg_archive );
3809
 
3810
    unless ( -d $sandbox_dpkg_archive )
3811
    {
3812
        Error("sandbox_dpkg_archive is not a directory: $sandbox_dpkg_archive")
3813
            unless $Clobber;
3814
        return;
3815
    }
3816
 
3817
    #
3818
    #   Need to supporttwo forms of pkgsuffix
3819
    #   With and without a leading '.'
3820
    #   
3821
    if (defined $pkgSuffix ) {
3822
        unless ($pkgSuffix =~ m~^\.~) {
3823
            $pkgSuffix = '.' . $pkgSuffix;
3824
        }
3825
    }
3826
 
3827
    #
3828
    #   Create a name for this package in the sandbox
3829
    #       Must use the package name and extension - unless exact sandbox
3830
    #       Must use packahe name, version and extension if its an exact sandbox
3831
    #
3832
    my $link_dir = "$sandbox_dpkg_archive/$pkgName";
3833
    my $base = 'sandbox' . $pkgSuffix; 
3834
    if ($sandbox_exact) {
3835
        $base = 'sandbox.' . $pkgVersion . $pkgSuffix; 
3836
    }
3837
 
3838
    return $link_dir, $base;
3839
}
3840
 
3841
#-------------------------------------------------------------------------------
227 dpurdie 3842
# Function        : BuildSandboxData
3843
#
3844
# Description     : Create data structures to allow this package to be built
3845
#                   within a multi-package sandbox.
3846
#
3847
#                   This will allow multiple components to work together
6133 dpurdie 3848
#                   Creates:
3849
#                       sandbox.int     - Rel path to the packages interface
3850
#                       sandbox.ffp     - Fast FingerPrint over the package body
3851
#                       sandbox.nob     - No Build marker
227 dpurdie 3852
#
3853
#                   Note: When called in Clobber-mode the link will be deleted
3854
#
3855
# Inputs          : $BUILDNAME              - The package name
3856
#                   $BUILDNAME_PROJECT      - Project extension
3857
#                   $::GBE_DPKG_SBOX        - Path of sandbox_dpkg_archive
3858
#                   $::GBE_DPKG             - Main repository
3859
#
3860
# Returns         : Nothing
3861
#
3862
sub BuildSandboxData
3863
{
3864
 
7452 dpurdie 3865
    my( $link_dir, $base) = genSandboxFile($BUILDNAME_PACKAGE, $BUILDNAME_VERSION, $BUILDNAME_SUFFIX );
3866
    return unless ( $link_dir );
227 dpurdie 3867
 
6133 dpurdie 3868
    my $nob_path  = $base . ".nob";
3869
    my $ffp_path  = $base . ".ffp";
3870
    my $int_path  = $base . ".int";
227 dpurdie 3871
 
6133 dpurdie 3872
    $nob_path = "$link_dir/$nob_path";
3873
    $ffp_path = "$link_dir/$ffp_path";
3874
    $int_path = "$link_dir/$int_path";
3875
 
227 dpurdie 3876
    if ( $Clobber )
3877
    {
3878
        rmdir $link_dir;            # Delete only if empty
3879
    }
3880
    else
3881
    {
6133 dpurdie 3882
        ToolsetFiles::AddFile($nob_path);
3883
        ToolsetFiles::AddFile($ffp_path);
3884
        ToolsetFiles::AddFile($int_path);
3885
 
3886
        #Log( "Sandbox Data. $base");
3887
        unlink $int_path;
227 dpurdie 3888
        mkdir $link_dir;
3889
 
3890
        #
6133 dpurdie 3891
        #   File with path to the interface directory
3892
        #   Relative to the base of the sandbox
227 dpurdie 3893
        #
6276 dpurdie 3894
        FileCreate($int_path, CatPaths('GBE_SANDBOX',RelPath($CwdFull,$::GBE_SANDBOX),$BUILDINTERFACE ));
227 dpurdie 3895
 
3896
        #
6133 dpurdie 3897
        #   Indicate packages not build on this machine
227 dpurdie 3898
        #
6133 dpurdie 3899
        unlink $nob_path;           # Delete the NoBuild marker
3900
        if ($NoBuild) {
3901
            TouchFile($nob_path);
3902
        }
227 dpurdie 3903
    }
3904
}
3905
 
3906
 
3907
#-------------------------------------------------------------------------------
3908
# Function        : BuildMake
3909
#
3910
# Description     : Generate the makefiles
3911
#                   This directive MUST be the last directive in the build.pl
3912
#                   file. The directive triggers the processing of all the
3913
#                   information that has been collected
3914
#
3915
#
3916
# Inputs          : None
3917
#
3918
# Returns         : Nothing
3919
#
3920
 
3921
sub BuildMake
3922
{
3923
    my( $argc, $platform );
3924
 
3925
    #
3926
    #   Must have a valid $BUILDINTERFACE
3927
    #   Normally this is held in the interface directory, but this is not
3928
    #   always created. If there is no $BUILDINTERFACE, then use the
3929
    #   build directory
3930
    #
6133 dpurdie 3931
    BuildInterfaceInternal($::ScmInterface) unless ( $BUILDINTERFACE );
227 dpurdie 3932
 
6133 dpurdie 3933
 
227 dpurdie 3934
    #.. Starting the build phase. No more data collection
3935
    #
305 dpurdie 3936
    StartBuildPhase();
3937
    LastBuildDirective();
227 dpurdie 3938
 
5109 dpurdie 3939
    #
3940
    #   Now that the bulk of the information has been displayed
3941
    #   we can display captured messages. These warnings will be 
3942
    #   at the end of the log so that users can see them.
3943
    DumpCapture();
3944
 
227 dpurdie 3945
    sub DeleteCfg
3946
    {
3947
        #
3948
        #   Delete files that will be re-created
3949
        #   Some of these files are read and written.
3950
        #   Errors in the files are solved by deleting the files now.
3951
        #
3952
        unlink "$BUILDINTERFACE/build.cfg";
3953
        unlink "$BUILDINTERFACE/Makefile.cfg";
3954
        unlink glob ("$BUILDINTERFACE/Makefile*.cfg");
3955
        unlink "$BUILDINTERFACE/Buildfile.cfg";
3956
        unlink "$BUILDINTERFACE/Dpackage.cfg";
3957
    }
3958
 
3959
    if ( $Clobber )                             # clobber mode ?
3960
    {
4003 dpurdie 3961
        #
3962
        #   Delete my own configuration files
3963
        #
227 dpurdie 3964
        DeleteCfg();
3965
 
3966
        #
3967
        #   JATS creates a 'pkg' directory for the target package
3968
        #
3969
        push @CLOBBERDIRS, "pkg";
3970
 
3971
        #
3972
        #   Deployment creates a 'build/deploy' directory
375 dpurdie 3973
        #   The 'build' directory may contain user files - only remove if empty
227 dpurdie 3974
        #
3975
        push @CLOBBERDIRS, "build/deploy";
375 dpurdie 3976
        push @REMOVEDIRS, "build";
227 dpurdie 3977
 
3978
        #
6133 dpurdie 3979
        #   List of files maintained by the build system
3980
        #
3981
        my @toolsetFiles = ToolsetFiles::GetFiles();
3982
 
3983
        #
227 dpurdie 3984
        #   Delete interface directories and other directories that have been
375 dpurdie 3985
        #   marked to be clobbered
227 dpurdie 3986
        #
3987
        foreach my $dir ( @CLOBBERDIRS )
3988
        {
3989
            next if ( $dir eq '.' );
3990
            next if ( $dir eq '..' );
3991
            if ( -d $dir )
3992
            {
361 dpurdie 3993
                RmDirTree ( $dir );
227 dpurdie 3994
            }
3995
        }
3996
 
375 dpurdie 3997
        foreach my $dir ( @REMOVEDIRS )
3998
        {
3999
            next if ( $dir eq '.' );
4000
            next if ( $dir eq '..' );
4001
            if ( -d $dir )
4002
            {
4003
                rmdir ( $dir ); # Only if empty
4004
            }
4005
        }
4006
 
6133 dpurdie 4007
        foreach my $file (@toolsetFiles)
227 dpurdie 4008
        {
6133 dpurdie 4009
            RmDirTree ( $file ) if ( -f $file );
227 dpurdie 4010
        }
4011
 
4012
        #
4013
        #   DPACKAGE may be a user file, Only delete it if we created it
4014
        #
299 dpurdie 4015
        unlink "$Srcdir/DPACKAGE.$::GBE_MACHTYPE" if $DeleteDPACKAGE;
227 dpurdie 4016
 
4017
        BuildPackageLink();
4018
        BuildSandboxData();
4019
        return;
4020
    }
6276 dpurdie 4021
    #
4022
    #   Generate the path to the descpkg file
4023
    #   The file is created later in the build proccess, but the makefile generation 
4024
    #   needs to have a known path to the file.
4025
    #    
4026
    #   It will be a file that is 'known' to JATS
4027
    #
4028
    $descpkgPath = BuildAddKnownFile ( $NoBuild ? $CwdFull : $Srcdir, 'descpkg' );
227 dpurdie 4029
 
4030
    #.. Build support files
4031
    #
4032
    DeleteCfg();
4033
    BuildConfig();
4034
    BuildSharedLibFiles();
4035
    WriteParsedBuildConfig();
4036
    BuildPackageLink();
4037
    BuildSandboxData();
4038
 
4039
    #
4040
    #  ONLY (re)building interface dir
4041
    #
6276 dpurdie 4042
    unless ( $Interface ) {
227 dpurdie 4043
 
6276 dpurdie 4044
        #---------------------------------------------------------------------------
4045
        #
4046
        #.. Make bootstrap "makefile",
4047
        #   Simulate a top level makefile
4048
        #       Pass argumenst to makelib
4049
        #       Sumulate SubDir() operations
4050
        #       Sumulate a Platform(*);
4051
        #
4052
        #       Due to the normal way that makelib.pl is executed,
4053
        #       the following substitutions are done.
4054
        #
4055
        @ARGV = ();
4056
        $0 = "makefile.pl ";
4057
        push @ARGV, "$CwdFull";                         # current working directory
4058
        push @ARGV, "$::GBE_TOOLS/makelib.pl";      # makelib.pl image
4059
        push @ARGV, "--interface=$BUILDINTERFACE"
4060
            if ($BUILDINTERFACE);
227 dpurdie 4061
 
6276 dpurdie 4062
        Debug( "ARGV:      @ARGV" );
227 dpurdie 4063
 
6276 dpurdie 4064
        #.. (re)Build root makefile
4065
        #
4066
        $ScmBuildlib = 0;                           # clear Buildlib flag for 'makelib.pl'
4067
        RootMakefile();                             # inform 'makelib.pl'
4068
        MakeLibInit();                              # run initialisation
227 dpurdie 4069
 
6276 dpurdie 4070
        #.. Register subdir(s)
4071
        #
4072
        UniquePush (\@BUILDSUBDIRS, $Srcdir );
4073
        SubDir( @BUILDSUBDIRS );
4074
        Platform( @BUILD_ACTIVEPLATFORMS );
227 dpurdie 4075
 
6276 dpurdie 4076
        #.. (re)build src makefiles and associated information
4077
        #   JatsTool will not return on error
4078
        #
4079
        my @cmds = ('jmake.pl', 'rebuild');
4080
        push @cmds, 'NORECURSE=1' if ( $RootOnly );
4081
        JatsTool ( @cmds);
4082
    }
4083
 
227 dpurdie 4084
    #
6276 dpurdie 4085
    #   Generate package signature
4086
    #   Write the descpkg file again - with a signature this time
4087
    #
4088
    ErrorConfig( 'name' => 'buildlib')   ;
4089
    WriteDescpkg();
4090
    NoBuildMarker();
305 dpurdie 4091
 
4092
    #
4093
    #   Generate some warnings that will be seen at the end of the build
4094
    #
4095
    Warning ("BuildSrcArchive Directive Present","Read JATS Manual for correct usage")
4096
        if ($build_source_pkg);
227 dpurdie 4097
}
4098
 
4099
 
4100
#-------------------------------------------------------------------------------
4101
# Function        : BuildVersion
4102
#
4103
# Description     : Generate version.c and version.h files
4104
#
4105
# Inputs          : Options
4106
#                       --Prefix=prefix         Text prepended to variables created
4107
#                                               as a part of the "C" versions
4108
#                       --Type=type             Type of "C" style data
4109
#                                               Allowed types are: array
4110
#                       --Defs=name             Generate a "C" definitions file.
4111
#                                               This file simply contains definitions
4112
#                       --Defs                  Same as --Defs=defs
4113
#                       --Style=style           Output file style
4114
#                                               Supported styles:
4115
#                                                   "C" - Default
4116
#                                                   "CSharp"
4117
#                                                   "WinRC"
289 dpurdie 4118
#                                                   "Delphi"
315 dpurdie 4119
#                                                   "VB"
227 dpurdie 4120
#                       --File=name             Specifies the output file name
4121
#                                               Default is determined by the style
4122
#
4123
#                   Also allows for an 'old' style format in which
4124
#                   the first three arguments are prefix,type and defs
4125
# Returns         :
4126
#
4127
 
4128
sub BuildVersion
4129
{
4130
    my ( $Prefix, $Type, $Mode ) = @_;
4131
    my $ModePrefix;
4132
    my $Style = "C";
4133
    my $FileName;
4134
    my $VersionFiles;
267 dpurdie 4135
    my @opts;
4136
    my $supports_opts;
227 dpurdie 4137
 
4138
    StartBuildPhase();                          # Starting the build phase. No more data collection
4139
 
279 dpurdie 4140
    if ( defined($Prefix) && $Prefix =~ /^-/ )
227 dpurdie 4141
    {
4142
        $Prefix = undef;
4143
        $Type = undef;
4144
        $Mode = undef;
4145
        foreach  ( @_ )
4146
        {
4147
            if (      /^--Prefix=(.*)/ ) {
4148
                $Prefix = $1;
4149
                $VersionFiles = 1;
4150
 
4151
            } elsif ( /^--Type=(.*)/ ) {
4152
                $Type = $1;
4153
                $VersionFiles = 1;
4154
 
4155
            } elsif ( /^--Defs=(.*)/ ) {
4156
                $Mode = $1;
4157
                $ModePrefix = "_$1";
4158
 
4159
            } elsif ( /^--Defs$/ ) {
4160
                $Mode = 'defs';
4161
                $ModePrefix = "";
4162
 
4163
            } elsif ( /^--Style=(.*)/ ) {
4164
                $Style = $1;
279 dpurdie 4165
                $VersionFiles = 1;
267 dpurdie 4166
                $supports_opts = 1 if ( $Style =~ /^WinRC/i );
227 dpurdie 4167
 
4168
            } elsif ( /^--File=(.*)/ ) {
4169
                $FileName = $1;
4170
 
267 dpurdie 4171
            } elsif ($supports_opts ) {
4172
                push @opts, $_;
235 dpurdie 4173
 
227 dpurdie 4174
            } else {
4175
                Error ("BuildVersion: Unknown option: $_");
4176
 
4177
            }
4178
        }
4179
    }
4180
    else
4181
    {
4182
        #
4183
        #   Old style positional arguments.
4184
        #
4185
        $VersionFiles = 1;
4186
        if ( defined( $Mode ) )
4187
        {
4188
            if ( $Mode =~ m/^defs(=(.*))?$/i )
4189
            {
4190
                $Mode       = $2 ? $2    : 'defs';
4191
                $ModePrefix = $2 ? "_$2" : "";
4192
            }
4193
            else
4194
            {
4195
                Error ("BuildVersion: Bad Mode argument. Need 'defs' or 'defs=name'");
4196
            }
4197
        }
4198
    }
4199
 
4200
    #
4201
    #   Determine the style of version file to create
4202
    #
4203
    if ( $Style =~ /^CSharp/i ) {
4204
        BuildVersionCSharp( $FileName );
4205
 
229 dpurdie 4206
    } elsif ( $Style =~ /^Properties/i ) {
4207
        BuildVersionProperties( $FileName, $Prefix );
4208
 
227 dpurdie 4209
    } elsif ( $Style =~ /^WinRC/i ) {
267 dpurdie 4210
        BuildVersionWinRC( $FileName, @opts );
227 dpurdie 4211
 
289 dpurdie 4212
    } elsif ( $Style =~ /^Delphi/i ) {
4213
        BuildVersionDelphi( $FileName, $Prefix );
315 dpurdie 4214
 
4215
    } elsif ( $Style =~ /^VB/i ) {
4216
        BuildVersionVB( $FileName, $Prefix );
289 dpurdie 4217
 
227 dpurdie 4218
    } elsif ( $Style eq "C" ) {
289 dpurdie 4219
        BuildVersionC    ( $FileName, $Prefix, $Type )     if ( $VersionFiles );
4220
        BuildVersionCdefs( $FileName, $Mode, $ModePrefix ) if ( $Mode );
227 dpurdie 4221
 
4222
    } else {
4223
        Error("BuildVersion: Unknown style: $Style");
4224
    }
4225
}
4226
 
4227
#-------------------------------------------------------------------------------
4228
# Function        : BuildDescpkg
4229
#
4230
# Description     : Create a package description file
4231
#                   The format of this file matches that generated by JANTS
4232
#                   Take care when extending the format
4233
#
4234
#                   NOTE: It turns out that JANTS is not a standard and the
4235
#                         implementors (of JANTS) kept on changing it.
6276 dpurdie 4236
#                         
4237
#                   NOTE: This directive is now ignored
4238
#                         The descpkg file is generated internally
227 dpurdie 4239
#
6276 dpurdie 4240
# Inputs          : $mode - 'Internal' - Skip sanity test
227 dpurdie 4241
#
4242
# Returns         :
4243
#
4244
sub BuildDescpkg
4245
{
6276 dpurdie 4246
    StartBuildPhase();                  # Starting the build phase. No more data collection
4247
}
4248
 
4249
#-------------------------------------------------------------------------------
4250
# Function        : WriteDescpkg 
4251
#
4252
# Description     : Create a package description file
4253
#                   The format of this file matches that generated by JANTS
4254
#                   Take care when extending the format
4255
#
4256
#                   NOTE: It turns out that JANTS is not a standard and the
4257
#                         implementors (of JANTS) kept on changing it.
4258
#
4259
# Inputs          :  
4260
#
4261
# Returns         : 
4262
#
4263
sub WriteDescpkg
4264
{
4003 dpurdie 4265
    return if ( $Clobber );                 # clobber mode ?
227 dpurdie 4266
 
261 dpurdie 4267
    my @desc;
279 dpurdie 4268
    push @desc, "Package Name:  $BUILDNAME_PACKAGE";
4269
    push @desc, "Version:       $BUILDVERSION";
4270
    push @desc, "Released By:   $::USER";
4271
    push @desc, "Released On:   $::CurrentTime";
4272
    push @desc, "Build Machine: $::GBE_HOSTNAME";
6276 dpurdie 4273
    push @desc, "Path:          $CwdFull";
279 dpurdie 4274
    push @desc, "Jats Version:  $::GBE_VERSION";
4275
    push @desc, "Jats Path:     $::GBE_CORE";
261 dpurdie 4276
    push @desc, "";
4277
    push @desc, "Build Dependencies:";
4278
    push @desc, "";
227 dpurdie 4279
 
4280
    foreach my $tag ( PackageEntry::GetPackageList )
4281
    {
4282
        my ($name, $version, $type) = PackageEntry::GetPackageData($tag);
4283
 
4284
        my @attributes;
4285
 
4286
        push @attributes, "name=\"$name\"";
4287
        push @attributes, "version=\"$version\"";
4288
        push @attributes, "build=\"true\"" if $type =~ /Build/i;
4289
 
261 dpurdie 4290
        push @desc, "<sandbox @attributes/>";
227 dpurdie 4291
    }
247 dpurdie 4292
 
6276 dpurdie 4293
    FileCreate ($descpkgPath, \@desc );
227 dpurdie 4294
}
4295
 
4296
#-------------------------------------------------------------------------------
4003 dpurdie 4297
# Function        : NoBuildMarker
4298
#
4299
# Description     : Maintain the nobuild marker
7452 dpurdie 4300
#                   This file is created to indicate that this build does nothing useful
4301
#                   Used by:
4302
#                       'create_dpkg' utility that this build does not do anything useful.
4303
#                                     but on a build machine we still need to generate a package fragment
4003 dpurdie 4304
#
7452 dpurdie 4305
#                   Used on a build machine by the build daemon
4306
#                   Used in a sandbox
4003 dpurdie 4307
#
4308
# Inputs          : None
4309
# Globals         : $NoBuild, $Clobber
4310
#
4311
# Returns         : Nothing
4312
#
4313
sub NoBuildMarker
4314
{
4315
    return if ( $Clobber );
4316
 
4317
    # Always delete the file - in case we toggle build forms
4318
    #
5986 dpurdie 4319
    my $markerFile = BuildAddKnownFile( $::ScmRoot, 'noBuild.gbe');
4003 dpurdie 4320
    unlink($markerFile);
4321
 
4322
    TouchFile($markerFile)
4323
        if ($NoBuild);
4324
}
4325
 
4326
#-------------------------------------------------------------------------------
227 dpurdie 4327
# Function        : BuildIncpkg
4328
#
4329
# Description     : Create a package inclusion file
4330
#
4331
# Inputs          :
4332
#
4333
# Returns         :
4334
#
4335
sub BuildIncpkg
4336
{
4337
    StartBuildPhase();                          # Starting the build phase. No more data collection
4338
    if ( $Clobber )                             # clobber mode ?
4339
    {
361 dpurdie 4340
        RmDirTree( "$Srcdir/incpkg" );
227 dpurdie 4341
        return;
4342
    }
4343
 
4344
    my $fh = ConfigurationFile::New( "$Srcdir/incpkg" );
4345
    $fh->Header( "buildlib (Version $BuildVersion)",
4346
                              "Package inclusion list" );
4347
 
4348
    foreach my $tag ( PackageEntry::GetPackageList )
4349
    {
4350
        my ($name, $version, $type) = PackageEntry::GetPackageData($tag);
4351
        $type = ($type =~ /build/i) ? "Build" : "Link";
4352
 
4353
        $fh->Write( "${type}PkgArchive( '$name', '$version' );\n" );
4354
    }
4355
 
4356
    $fh->Close();
4357
}
4358
 
4359
#-------------------------------------------------------------------------------
4360
# Function        : BuildConfig
4361
#
4362
# Description     : Create the file interface/build.cfg
4363
#                   This file contains information gathered by the build process
4364
#                   that is to be used when makefiles are created and re-created
4365
#
4366
# Inputs          : None
4367
#
4368
# Returns         : Nothing
4369
#
283 dpurdie 4370
sub BuildConfig
227 dpurdie 4371
{
4372
    Error( "No BuildInterface directive encountered\n" )
4373
        unless ($BUILDINTERFACE);
4374
 
4375
    my $fh = ConfigurationFile::New( "$BUILDINTERFACE/build.cfg");
4376
    $fh->Header( "buildlib (Version $BuildVersion)",
4377
                              "Makelib configuration file", "
4378
\$ScmBuildMachType              = \"$::GBE_MACHTYPE\";
4379
\$ScmInterfaceVersion           = \"$::InterfaceVersion\";
4380
\$ScmBuildName                  = \"$BUILDNAME\";
4381
\$ScmBuildPackage               = \"$BUILDNAME_PACKAGE\";
4382
\$ScmBuildVersion               = \"$BUILDNAME_VERSION\";
4383
\$ScmBuildProject               = \"$BUILDNAME_PROJECT\";
4384
\$ScmBuildVersionFull           = \"$BUILDVERSION\";
6511 dpurdie 4385
\$ScmBuildBaseVersion           = \"$BUILDBASEVERSION\";
227 dpurdie 4386
\$ScmBuildPreviousVersion       = \"$BUILDPREVIOUSVERSION\";
4387
\$ScmLocal                      = \"$BUILDLOCAL\";
4388
\$ScmDeploymentPatch            = \"$DEPLOY_PATCH\";
4389
\$ScmSrcDir                     = \"$Srcdir\";
4390
\$ScmBuildSrc                   = \"$ScmBuildSrc\";
4391
\$ScmExpert                     = \"$Expert\";
261 dpurdie 4392
\$ScmAll                        = \"$All\";
4003 dpurdie 4393
\$ScmNoBuild                    = \"$NoBuild\";
6177 dpurdie 4394
\$ScmBuildUuid                  = \"$BUILD_UUID\";
227 dpurdie 4395
");
4396
 
4397
#.. Alias
4398
#
4399
    $fh->DumpData(
4400
        "\n# Aliases.\n#\n",
4401
        "ScmBuildAliases", \%BUILDALIAS );
4402
 
4403
#.. Products
4404
#
4405
    $fh->DumpData(
4406
        "# Product mapping.\n#\n",
4407
        "ScmBuildProducts", \%BUILDPRODUCT_PARTS );
4408
 
4409
#.. Create ScmBuildPlatforms
4410
#
4411
    my( @platforms_merged, %platform_args ) = ();
4412
 
4413
    UniquePush ( \@platforms_merged, @BUILDPLATFORMS );
4414
 
4415
    foreach my $key ( keys %BUILDPRODUCT ) {
4416
        my( @list ) = split( ' ', $BUILDALIAS{ $key } || '' );
4417
        my( $platform );
4418
 
4419
        foreach my $elem ( @list ) {
4420
            if ( $elem =~ /^--/ ) {             # argument
4421
                HashJoin( \%platform_args, $;, $platform, $elem )
4422
                    if ( defined($platform) );
4423
                next;
4424
            }
4425
            $platform = $elem;                  # platform
4426
            UniquePush( \@platforms_merged, $elem );
4427
        }
4428
    }
4429
 
4430
#.. Create ScmBuildPlatforms
4431
#   Contains per platform options extracted from alias and platform args
4432
#
4433
    my %ScmBuildPlatforms;
4434
    foreach my $key ( @platforms_merged ) {
4435
 
6276 dpurdie 4436
        my $pInfo = $BUILDINFO{$key};
4437
        next if ($pInfo->{NOT_AVAILABLE});
4438
 
227 dpurdie 4439
        my( @arguments ) = ();
4440
        UniquePush( \@arguments, split( /$;/, $BUILDPLATFORMARGS{ $key } ))
4441
            if ( exists $BUILDPLATFORMARGS{ $key } );
4442
 
4443
        UniquePush( \@arguments, split( /$;/, $platform_args{ $key } ))
4444
            if ( exists $platform_args{ $key } );
4445
 
4446
        $ScmBuildPlatforms{$key} = join "$;", @arguments;
4447
    }
4448
 
4449
    $fh->DumpData(
4450
        "# Platform and global argument list.\n#\n",
4451
        "ScmBuildPlatforms", \%ScmBuildPlatforms );
4452
 
6276 dpurdie 4453
#.. Create ScmBuildMatrix
4454
#   Contains information on all the platforms that the package builds for and target machines
4455
#   
4456
    my %ScmBuildMatrix;
4457
    foreach my $key ( keys %BUILDINFO ) {
4458
        my $pInfo = $BUILDINFO{$key};
4459
        next if exists ($pInfo->{BADNAME});
4460
        next if ($pInfo->{NOT_AVAILABLE} > 1);
4461
        Error ("Internal: No MACHTYPE provided for $key") unless exists $pInfo->{MACHTYPE};
4462
        $ScmBuildMatrix{$key} = $pInfo->{MACHTYPE};
4463
    }
227 dpurdie 4464
 
6276 dpurdie 4465
    $fh->DumpData(
4466
        "# Build Matrix.\n#\n",
4467
        "ScmBuildMatrix", \%ScmBuildMatrix );
4468
 
227 dpurdie 4469
# .. Create BuildPkgRules
4470
#
367 dpurdie 4471
#    This is most of the information contained within %PKGRULES, which
227 dpurdie 4472
#    requires additional processing within makelib.
4473
#
367 dpurdie 4474
#   Need the True Path for windows.
4475
#       Some makefile functions (wildcard) only work as expected
4476
#       if the case of the pathname is correct. Really only a problem
4477
#       with badly formed legecy packages where the Windows user
4478
#       guessed at the package format.
4479
#
227 dpurdie 4480
    my %ScmBuildPkgRules;
4481
    foreach my $platform ( keys %PKGRULES )
4482
    {
4483
        foreach my $package ( @{$PKGRULES{$platform}} )
4484
        {
6684 dpurdie 4485
            next if exists $package->{'EXCLUDE'};
227 dpurdie 4486
            my %entry;
4487
 
367 dpurdie 4488
            $entry{ROOT}     = TruePath( $package->{'base'} );
227 dpurdie 4489
            $entry{NAME}     = $package->{'name'};
4490
            $entry{VERSION}  = $package->{'version'};
4491
            $entry{DNAME}    = $package->{'dname'};
4492
            $entry{DVERSION} = $package->{'dversion'};
4493
            $entry{DPROJ}    = $package->{'dproj'};
4494
            $entry{TYPE}     = $package->{'type'};
4495
            $entry{CFGDIR}   = $package->{'cfgdir'} if ( defined( $package->{'cfgdir'} ) );
4496
 
367 dpurdie 4497
            foreach my $dir (qw (TOOLDIRS) )
227 dpurdie 4498
            {
4499
                $entry{$dir} = $package->{$dir} ;
4500
            }
4501
 
367 dpurdie 4502
            my $baselen = length($package->{'base'});
4503
            foreach my $dir (qw (PINCDIRS PLIBDIRS THXDIRS) )
4504
            {
4505
                $entry{$dir} = [];
4506
                foreach my $file ( @{$package->{$dir}} )
4507
                {
4508
                    push @{$entry{$dir}}, substr TruePath($package->{'base'} . $file ), $baselen;
4509
                }
4510
            }
4511
 
227 dpurdie 4512
            push @{$ScmBuildPkgRules{$platform}}, \%entry;
4513
        }
4514
    }
4515
 
4516
    $fh->DumpData(
4517
        "# Imported packages.\n#\n",
4518
        "ScmBuildPkgRules", \%ScmBuildPkgRules );
4519
 
4520
#
4521
#   BUILDPLATFORMS,
4522
#       The value that is saved only contains the active platforms
4523
#
4524
#   DEFBUILDPLATFORMS,
4525
#       The value that is matchs the wildcard specification for Platform 
4526
#       directives.
4527
#
4528
    $fh->DumpData(
4529
        "# A list of platforms active within the view.\n#\n",
4530
        "BUILDPLATFORMS", \@BUILD_ACTIVEPLATFORMS );
4531
 
4532
    $fh->DumpData(
4533
        "# A list of default platforms within the view.\n#\n",
4534
        "DEFBUILDPLATFORMS", \@DEFBUILDPLATFORMS );
4535
 
4536
#
4537
#   BUILDTOOLS
4538
#       A list of toolset extension paths
4539
#
4540
    $fh->DumpData(
4541
        "# A list of paths with toolset extension programs.\n#\n",
4542
        "BUILDTOOLSPATH", \@BUILDTOOLS );
4543
 
4544
#
4545
#   BUILDPLATFORM_PARTS
4546
#       A subset of BUILDINFO exported as BUILDPLATFORM_PARTS
4547
#       This exists only for backward compatability with existing code
4548
#       in external packages ( deployfiles).
4549
#
4550
#   Only save those parts that are part of the current build
4551
#   This will prevent users attempting to build for platforms that have not
4552
#   been correctly constructed.
4553
#
4554
    my %active =  map { ${_} => 1 } @BUILD_ACTIVEPLATFORMS;
4555
    my %active_buildplatform_parts;
4556
    my %active_build_info;
4557
    foreach ( keys %BUILDINFO )
4558
    {
4559
        next unless ( $active{$_} );
4560
        $active_buildplatform_parts{$_} = $BUILDINFO{$_}{PARTS};
4561
        $active_build_info{$_}          = $BUILDINFO{$_};
4562
    }
4563
 
4564
    $fh->DumpData(
4565
        "# Parts of all platforms.\n#\n",
4566
        "BUILDPLATFORM_PARTS", \%active_buildplatform_parts );
4567
#
4568
#   BUILDINFO
4569
#       Complete TARGET Information
4570
#
4571
    $fh->DumpData(
4572
        "# Extended build information.\n#\n",
4573
        "BUILDINFO", \%active_build_info );
4574
 
4575
#
247 dpurdie 4576
#   BUILD_KNOWNFILES
4577
#       All paths are relative to the project root directory
4578
#       ie: The directory that conatins the build.pl file
4579
#
4580
    $fh->DumpData(
4581
        "# Generated Files that may be known when used as Src files.\n#\n",
4582
        "BUILD_KNOWNFILES", \%BUILD_KNOWNFILES );
4583
 
4584
#
227 dpurdie 4585
#   Close out the file
4586
#
4587
    $fh->Close();
363 dpurdie 4588
 
227 dpurdie 4589
}
4590
 
4591
#-------------------------------------------------------------------------------
4592
# Function        : WriteParsedBuildConfig
4593
#
4594
# Description     : Write all the parsed build.pl data to a single file
4595
#                   Its all in there for use
4596
#
4597
# Inputs          : 
4598
#
4599
# Returns         : 
4600
#
4601
sub WriteParsedBuildConfig
4602
{
4603
    my $cfg_file = "$::BUILDINTERFACE/Buildfile.cfg";
4604
    my %cf_build_info = ();
4605
 
4606
    #
4607
    #   Examine the symbol table and capture most of the entries
4608
    #
4609
    foreach my $symname (keys %main::)
4610
    {
4611
        next if ( $symname =~ m/::/  );                 # No Typeglobs
4612
        next if ( $symname =~ m/^cf_build_info/  );     # Not myself
4613
        next unless ( $symname =~ m/^[A-Za-z]/  );      # No system type names
4614
        next if ( $symname =~ m/^SIG$/  );              # Useless
4615
        next if ( $symname =~ m/^ENV$/  );              # Don't keep the user ENV
4616
        next if ( $symname =~ m/^INC$/  );              # Don't keep the INC paths
4617
        next if ( $symname =~ m/^DEFINES/  );           # Don't keep
4618
        next if ( $symname =~ m/^TOOLSETRULES/  );      # Don't keep
4619
 
331 dpurdie 4620
        no strict 'vars';
227 dpurdie 4621
        local *sym = $main::{$symname};
4622
 
331 dpurdie 4623
        $cf_build_info{"\$$symname"} =  $sym if defined $sym;
369 dpurdie 4624
        $cf_build_info{"\@$symname"} = \@sym if @sym;
4625
        $cf_build_info{"\%$symname"} = \%sym if %sym;
331 dpurdie 4626
        use strict 'vars';
227 dpurdie 4627
    }
4628
 
4629
    #
4630
    #   Dump out the configuration information
4631
    #
4632
    my $fh = ConfigurationFile::New( "$cfg_file" );
4633
    $fh->Header( "buildlib (version $::BuildVersion)",
4634
                              "Buildfile configuration" );
4635
    $fh->Dump( [\%cf_build_info], [qw(*cf_build_info)] );
4636
    $fh->Close();
4637
}
4638
 
4639
 
4640
#-------------------------------------------------------------------------------
4641
# Function        : BuildSharedLibFiles
4642
#
4643
# Description     : Create a file in the interface directory that will specify
4644
#                   the locations of shared libraries.
4645
#
4646
#                   Note: Always create a file as makefile targets depend on it.
4647
#
4648
#                   This is a bit ugly.
4649
#
4650
#                   There needs be an association between the build machine and
4651
#                   the target platform. Need to know if the current target is
4652
#                   native to the current build machine. If it is then we can
4653
#                   run tests on the machine and we then need to extend the
4654
#                   search path for the target.
4655
#
4656
#                   The BUILDINFO{EXT_SHARED} is used to control the creation of
4657
#                   the files by specifying the extension of the file.
4658
#
4659
# Inputs          : None
4660
#
4661
# Returns         :
4662
#
4663
sub BuildSharedLibFiles
4664
{
4665
    if ( $ScmHost eq "DOS" || $ScmHost eq "WIN" ) {
4666
        BuildSharedLibFiles_WIN(@_);
4667
 
4668
    } elsif ( $ScmHost eq "Unix" ) {
4669
        BuildSharedLibFiles_Unix(@_);
4670
 
4671
    } else {
4672
        Error("Cannot build. Unknown machine type: $ScmHost",
4673
              "Need WIN, DOS or Unix" );
4674
    }
4675
}
4676
 
4677
#-------------------------------------------------------------------------------
4678
# Function        : BuildSharedLibFiles_WIN
4679
#
4680
# Description     : Implementation of BuildSharedLibFiles for Windows
4681
#
4682
# Inputs          : None
4683
#
4684
sub BuildSharedLibFiles_WIN
4685
{
4686
 
4687
    foreach my $platform ( @BUILD_ACTIVEPLATFORMS )
4688
    {
6504 dpurdie 4689
        my @pathList;
4690
        if (exists $BUILDINFO{$platform}{EXT_SHARED} ) {
4691
            push @pathList, reverse BuildSharedLibFiles_list( $platform, $BUILDINFO{$platform}{EXT_SHARED} );
4692
        }
4693
        push @pathList, @BUILDTOOLS; 
227 dpurdie 4694
 
4695
        #
4696
        #   Create a .bat file for WIN32
4697
        #   This may be consumed by user wrapper programs
4698
        #
229 dpurdie 4699
        #   Features: No Echo
4700
        #             Use of SETLOCAL to prevent pollution of environment
4701
        #
227 dpurdie 4702
        my $fh = ::ConfigurationFile::New( "$BUILDINTERFACE/set_$platform.bat", '--NoEof', '--Type=bat' );
229 dpurdie 4703
        $fh->Write ( "\@echo off\n");
227 dpurdie 4704
        $fh->Header( "Buildlib ($BuildVersion)","Shared Library Paths" );
229 dpurdie 4705
        $fh->Write ( "\nSETLOCAL\n");
6511 dpurdie 4706
        foreach ( @pathList ) {
227 dpurdie 4707
            $_ =~ s~/~\\~g;
4708
            $fh->Write ( "PATH=$_;\%PATH\%\n" );
4709
        }
4710
        $fh->Write ( "\n%*\n" );
229 dpurdie 4711
        $fh->Write ( "\nENDLOCAL\n");
231 dpurdie 4712
        $fh->Write ( "EXIT /B %ERRORLEVEL%\n");
227 dpurdie 4713
        $fh->Close();
4714
 
4715
        #
4716
        #   Create a .sh file for WIN32
4717
        #   This may be consumed by a shell - as used within JATS
4718
        #
4719
        $fh = ::ConfigurationFile::New( "$BUILDINTERFACE/set_$platform.sh", '--NoEof', '--Type=sh' );
4720
        $fh->Header( "Buildlib ($BuildVersion)","Shared Library Paths" );
6511 dpurdie 4721
        foreach ( @pathList ) {
227 dpurdie 4722
            tr~\\/~/~s;
4723
            $fh->Write ( "PATH=$_\\;\$PATH\n" );
4724
        }
287 dpurdie 4725
        $fh->Write ( "\n" . '[ -n "$*" ] && "$@"'  ."\n" );
227 dpurdie 4726
        $fh->Close();
4727
    }
4728
}
4729
 
4730
#-------------------------------------------------------------------------------
4731
# Function        : BuildSharedLibFiles_Unix
4732
#
4733
# Description     : Implementation of BuildSharedLibFiles for Unix
4734
#                   Extend the Shared Library search path via LD_LIBRARY_PATH
5877 dpurdie 4735
#                   
4736
#                   Create sonames for all external shared libraries
227 dpurdie 4737
#
4738
# Inputs          : None
4739
#
4740
sub BuildSharedLibFiles_Unix
4741
{
4742
    foreach my $platform ( @BUILD_ACTIVEPLATFORMS )
4743
    {
6504 dpurdie 4744
        my @unix_paths;
4745
        if ( exists $BUILDINFO{$platform}{EXT_SHARED} ) {
4746
            @unix_paths = BuildSharedLibFiles_list( $platform, $BUILDINFO{$platform}{EXT_SHARED} );
227 dpurdie 4747
 
6504 dpurdie 4748
            #
4749
            #   Create sonames for all shared libraries
4750
            #   Append to the begging of the search list - so that it will rendered last
4751
            #   
4752
            my $sodir = BuildSoNameLinks_Unix($platform, @unix_paths);
4753
            unshift( @unix_paths, $sodir ) if defined $sodir;
4754
        }
5877 dpurdie 4755
 
4756
        #
227 dpurdie 4757
        #   Create a .sh file for Unix
4758
        #
229 dpurdie 4759
        my $file = "$BUILDINTERFACE/set_$platform.sh";
4760
        my $fh = ::ConfigurationFile::New( $file , '--NoEof', '--Type=sh' );
227 dpurdie 4761
        $fh->Header( "Buildlib ($BuildVersion)","Shared Library Paths" );
6511 dpurdie 4762
        foreach ( reverse @unix_paths, @BUILDTOOLS ) {
227 dpurdie 4763
            $fh->Write ( "export LD_LIBRARY_PATH=$_:\$LD_LIBRARY_PATH\n" );
4764
        }
6504 dpurdie 4765
 
4766
        #
4767
        #   Extend the search path to allow tools to be located
6511 dpurdie 4768
        #   Have already extended LD_LIBRARY_PATH to allow for tools shared libaraies 
6504 dpurdie 4769
        #   
4770
        $fh->Write ( "\n# Extend Tool Search Path\n" );
4771
        foreach ( @BUILDTOOLS ) {
4772
            tr~\\/~/~s;
6511 dpurdie 4773
            $fh->Write ( "PATH=$_:\$PATH\n" );
6504 dpurdie 4774
        }
4775
 
275 dpurdie 4776
        $fh->Write ( "\n\"\$\@\"\n" );
227 dpurdie 4777
        $fh->Close();
229 dpurdie 4778
 
4779
        #
4780
        #   Make the file executable under unix
4781
        #
4782
        chmod 0755, $file;
227 dpurdie 4783
    }
4784
}
4785
 
4786
#-------------------------------------------------------------------------------
5877 dpurdie 4787
# Function        : BuildSoNameLinks_Unix 
4788
#
4789
# Description     : Generate soname links for all shared libraries from external
4790
#                   packages.
4791
#                   
4792
#                   There is a bit of a cheat. We don't examine the library to determine
4793
#                   the soname. We simple create all possible sonames to the library
4794
#
4795
# Inputs          : $platform       - Target platform
4796
#                   @paths          - Array of paths to scan for libraries 
4797
#
4798
# Returns         : soLinkDir       - Absolute path to the directory of gernerated
4799
#                                     symlinks
4800
#
4801
sub BuildSoNameLinks_Unix
4802
{
4803
    my ($platform, @paths) = @_;
4804
    my $soLinkDir = catdir($BUILDINTERFACE, 'soLinks', $platform );
4805
 
4806
    Verbose("Create Unix SoName links - $soLinkDir");
4807
    RmDirTree( $soLinkDir );
4808
 
4809
    #
4810
    #   Search provided library paths for shared libaries
4811
    #       These are names of the form *.so.* ie : libz.so.1.2.5
4812
    #
4813
    foreach my $path (@paths)
4814
    {
4815
        foreach my $file (glob(catdir($path, '*.so.*')))
4816
        {
4817
            #
4818
            #   Skip the debug symbol files
4819
            #
4820
            next if $file =~ m~\.debug$~;
4821
            next if $file =~ m~\.dbg$~;
4822
 
4823
            #
4824
            #   Generate all possible sonames by removing .nnnn from the 
4825
            #   end of the file name
4826
            #   
4827
            my $sofile = $file;
4828
            while ($sofile =~ m~(.*)\.\d+$~)
4829
            {
4830
                $sofile = $1;
4831
                unless (-f $sofile) {
4832
                    Verbose2("Need Soname: $sofile");
4833
 
4834
                    #
4835
                    #   Create link from soname to full name
4836
                    #   
4837
                    mkpath ( $soLinkDir ) unless -d $soLinkDir;
4838
                    my $sofilename = $sofile;
4839
                    $sofilename =~ s~.*/~~;
4840
                    $sofilename = catdir($soLinkDir, $sofilename);
4841
                    unless (-f $sofilename) {
4842
                        symlink ($file, $sofilename) || Error ("Cannot create symlink to $sofilename. $!"); 
4843
                    }
4844
                }
4845
            }
4846
        }
4847
    }
4848
 
4849
    #
4850
    #   Return the path the generated soLink dir
4851
    #
4852
    return AbsPath($soLinkDir) if (-d $soLinkDir);
4853
    return undef;
4854
}
4855
 
4856
#-------------------------------------------------------------------------------
227 dpurdie 4857
# Function        : BuildSharedLibFiles_list
4858
#
4859
# Description     : Determine a list of Shared Library paths that can be used
4860
#                   by the current target
4861
#
4862
# Inputs          : $platform       - Current platform
4863
#                   $so             - Shared object extensions
4864
#
4865
# Returns         : List of search paths
4866
#
4867
sub BuildSharedLibFiles_list
4868
{
4869
    my ($platform, $so ) = @_;
4870
    my @paths;
4871
    my @parts = @{$BUILDINFO{$platform}{PARTS}};
4872
 
4873
    #
4874
    #   Paths from the current build
4875
    #       Local directory         - for installed components
4876
    #       Interface directory     - for BuildPkgArchives
4877
    #
4878
    if ( $BUILDLOCAL )
4879
    {
5986 dpurdie 4880
        my @localParts;
4881
        UniquePush \@localParts, $BUILDINFO{$platform}{PLATFORM} , $BUILDINFO{$platform}{PRODUCT}, $BUILDINFO{$platform}{TARGET};
4882
        foreach ( @localParts )
227 dpurdie 4883
        {
4884
            push @paths, AbsPath("$BUILDLOCAL/lib/$_");
4885
        }
4886
    }
4887
 
4888
    foreach ( @parts )
4889
    {
4890
            push @paths, AbsPath("$BUILDINTERFACE/lib/$_");
4891
    }
4892
 
4893
    #
4894
    #   For each LinkPkgArchive
4895
    #
4896
    foreach my $package ( @{$PKGRULES{$platform}} )
4897
    {
4898
        next unless ( $package->{'type'} eq 'link' );
4899
 
4900
        my $base = $package->{'base'};
4901
        for my $path ( @{$package->{'PLIBDIRS'}} )
4902
        {
289 dpurdie 4903
            my @so_libs;
317 dpurdie 4904
            push @so_libs, glob ( "$base$path/*$_") foreach ( ArrayList($so) );
227 dpurdie 4905
            next unless scalar @so_libs;
4906
            push @paths, $base . $path;;
4907
        }
4908
    }
4909
 
4910
    #
4911
    #   Returns paths found
4912
    #
4913
    return @paths;
4914
}
4915
 
4916
#-------------------------------------------------------------------------------
247 dpurdie 4917
# Function        : BuildAddKnownFile
4918
#
4919
# Description     : Save the file as a file that will be known  to the JATS
4920
#                   makefiles. It will be available SRCS, but will not be a
4921
#                   part of any object list.
4922
#
4923
#                   Known Files will be deleted on clobber
4924
#
4925
# Inputs          : $path
4926
#                   $file
289 dpurdie 4927
#                   $noadd                    - Don't add to known
247 dpurdie 4928
#
4929
# Returns         : Path and filename
4930
#
4931
 
4932
sub BuildAddKnownFile
4933
{
289 dpurdie 4934
    my ($path, $file, $noadd) = @_;
247 dpurdie 4935
    $path .= '/'. $file;
2450 dpurdie 4936
    $path =~ tr~/~/~s;
289 dpurdie 4937
    $BUILD_KNOWNFILES {$file} = $path
4938
        unless ( defined($noadd) && $noadd);
4003 dpurdie 4939
 
6133 dpurdie 4940
    ToolsetFiles::AddFile( $path )
3967 dpurdie 4941
        unless ($Clobber);
4942
 
247 dpurdie 4943
    return $path;
4944
}
4945
 
4946
#-------------------------------------------------------------------------------
5969 dpurdie 4947
# Function        : WinPath 
4948
#
4949
# Description     : Covert path to a windows formatted path
4950
#
4951
# Inputs          : One path element
4952
#
4953
# Returns         : One ugly path element
4954
#
4955
 
4956
sub WinFullPath
4957
{
4958
    my ($path) = @_;
4959
    $path = FullPath($path);
4960
    $path =~ tr~\\/~\\~s;
4961
    return $path;
4962
}
4963
 
4964
#-------------------------------------------------------------------------------
4965
# Function        : BuildPropertyPages 
4966
#
4967
# Description     : Create a props file suitable for use by VS2010, VS2012 (possibly others)
4968
#                   Only supported for C/C++ projects
4969
#                   Provide info for:
4970
#                       Include Search paths
4971
#                       Library search paths
4972
#                       Nice Macros 
4973
#
4974
# Inputs          : 
4975
#
4976
# Returns         : 
4977
#
4978
sub BuildPropertyPages
4979
{
4980
    StartBuildPhase();                      # Starting the build phase. No more data collection
5986 dpurdie 4981
    return if $Clobber;
5969 dpurdie 4982
    foreach my $platform ( keys %BUILDINFO )
4983
    {
4984
        next unless $BUILDINFO{$platform}{MSBUILDPROPS};
5986 dpurdie 4985
        my $propsFile = BuildAddKnownFile ($Srcdir, 'jats_'. $BUILDINFO{$platform}{TARGET} . '.props');
4986
 
5969 dpurdie 4987
        Message("BuildPropertyPages: $propsFile");
4988
 
4989
        my %macros;
4990
        my @libpaths;
4991
        my @incpaths;
4992
        my @parts = @{$BUILDINFO{$platform}{PARTS}};
4993
 
4994
        #
4995
        #   Basic definitions
4996
        #   
4997
        $macros{'GBE_ROOT'}     = WinFullPath(".");
4998
        $macros{'GBE_PLATFORM'} = $BUILDINFO{$platform}{PLATFORM};
4999
        $macros{'GBE_PRODUCT'}  = $BUILDINFO{$platform}{PRODUCT};
5000
        $macros{'GBE_TARGET'}   = $BUILDINFO{$platform}{TARGET};
5001
        $macros{'GBE_MACHTYPE'} = $::GBE_MACHTYPE;
5002
        $macros{'GBE_PKGDIR'}   = WinFullPath('./pkg/' . $BUILDNAME_PACKAGE);
5003
        $macros{'GBE_BUILDNAME'}= $BUILDNAME_PACKAGE;
5004
 
5005
        #
5006
        #   Paths from the current build
5007
        #       Local directory         - for installed components
5008
        #       Interface directory     - for BuildPkgArchives
5009
        #
5010
        if ( $BUILDLOCAL )
5011
        {
5012
            my $macroName = 'GBE_LOCALDIR';
5013
            $macros{$macroName} = WinFullPath("$BUILDLOCAL") ;
5014
            $macroName = '$(' . $macroName . ')';
5986 dpurdie 5015
            my @localParts;
5016
            UniquePush \@localParts, $BUILDINFO{$platform}{PLATFORM} , $BUILDINFO{$platform}{PRODUCT}, $BUILDINFO{$platform}{TARGET};
5017
            foreach ( @localParts )
5969 dpurdie 5018
            {
5019
                push @libpaths, catdir($macroName, 'lib', $_);
5020
                push @incpaths, catdir($macroName ,'include' ,$_);
5021
            }
5022
            push @incpaths, catdir($macroName ,'include');
5023
        }
5024
 
5025
        my $macroName = 'GBE_INTERFACEDIR';
5026
        $macros{$macroName} = WinFullPath("$BUILDINTERFACE") ;
5027
        $macroName = '$(' . $macroName . ')';
5028
 
5029
        foreach ( @parts )
5030
        {
5031
                push @libpaths, catdir($macroName, 'lib' , $_);
5032
                push @incpaths, catdir($macroName ,'include' ,$_);
5033
        }
5034
        push @incpaths, catdir($macroName ,'include');
5035
 
5036
        #
5037
        #   For each LinkPkgArchive
5038
        #
5039
        foreach my $package ( @{$PKGRULES{$platform}} )
5040
        {
5041
            next unless ( $package->{'type'} eq 'link' );
5042
 
5043
            my $macroName = 'GBE_PACKAGE_'.$package->{'name'};
5044
            $macros{$macroName} = WinFullPath($package->{'base'}) ;
5045
            $macroName = '$(' . $macroName . ')';
5046
 
5047
            for my $path ( @{$package->{'PLIBDIRS'}} )
5048
            {
5049
                push @libpaths, catdir($macroName, $path);
5050
            }
5051
            for my $path ( @{$package->{'PINCDIRS'}} )
5052
            {
5053
                push @incpaths, catdir($macroName, $path);
5054
            }
5055
        }
5056
 
5057
        my $AdditionalIncludeDirectories = join(';', @incpaths );
5058
        my $AdditionalLibraryDirectories = join(';', @libpaths);
5059
        my $PreprocessorDefinitions = 'JATS=1';
5060
 
5061
        #
5062
        #   Create a props file formatted for VS2012
5063
        #
5064
        open (my $XML, '>', $propsFile) || Error ("Cannot create output file: $propsFile", $!);
5065
 
5066
        my $writer = XML::Writer->new(OUTPUT => $XML, UNSAFE => 0, DATA_INDENT => 4, DATA_MODE => 1);
5067
        $writer->xmlDecl("UTF-8");
5068
        $writer->comment('This file is generated by JATS build');
5069
        $writer->comment('Do not edit this file');
5070
        $writer->comment('Do not version control this file');
5071
        $writer->startTag('Project', "ToolsVersion", "4.0", "xmlns", "http://schemas.microsoft.com/developer/msbuild/2003");
5072
        $writer->emptyTag('ImportGroup', 'Label' , "PropertySheets");
5073
 
5074
        #
5075
        #   Special Macro for handling production/debug libraries
5076
        #
5077
        $writer->startTag('PropertyGroup', 'Label' , "UserMacros", 'Condition', "'\$(Configuration)' == 'Debug'");
5078
        $writer->dataElement('GBE_TYPE', 'D');
5079
        $writer->endTag('PropertyGroup');
5080
 
5081
        $writer->startTag('PropertyGroup', 'Label' , "UserMacros", 'Condition', "'\$(Configuration)' != 'Debug'");
5082
        $writer->dataElement('GBE_TYPE', 'P');
5083
        $writer->endTag('PropertyGroup');
5084
 
5085
        #
5086
        #   Define macros
5087
        #   
5088
        $writer->startTag('PropertyGroup', 'Label' , "UserMacros");
5089
        foreach my $key ( sort keys %macros)
5090
        {
5091
            $writer->dataElement($key, $macros{$key});
5092
        }
5093
        $writer->endTag('PropertyGroup');
5094
        $macros{'GBE_TYPE'}     = 1;
5095
 
5096
        #
5097
        #   Extend the search paths for includes and libaraies
5098
        #   
5099
        #$writer->emptyTag('ItemDefinitionGroup');
5100
        $writer->startTag('ItemDefinitionGroup');
5101
 
5102
        $writer->startTag('ClCompile');
5103
        $writer->dataElement('AdditionalIncludeDirectories', $AdditionalIncludeDirectories . ';%(AdditionalIncludeDirectories)');
5104
        $writer->dataElement('PreprocessorDefinitions', $PreprocessorDefinitions . ';%(PreprocessorDefinitions)');
5105
        $writer->endTag('ClCompile');
5106
 
5107
        $writer->startTag('Link');
5108
        $writer->dataElement('AdditionalLibraryDirectories', $AdditionalLibraryDirectories . ';%(AdditionalLibraryDirectories)');
5109
        $writer->endTag('Link');
5110
        $writer->endTag('ItemDefinitionGroup');
5111
 
5112
        #
5113
        #   Specify all macro names
5114
        #
5115
        $writer->startTag('ItemGroup');
5116
        foreach my $key ( sort keys %macros)
5117
        {
5118
            $writer->startTag('BuildMacro', 'Include' , $key);
5119
            $writer->dataElement('Value', '$(' . $key . ')');
5120
            $writer->endTag('BuildMacro');
5121
        }
5122
 
5123
        #
5124
        #   Close tags and write the XML file
5125
        #
5126
        $writer->endTag('ItemGroup');
5127
        $writer->endTag('Project');
5128
        $writer->end();
5129
    }
5130
}
5131
 
5132
 
5133
#-------------------------------------------------------------------------------
227 dpurdie 5134
# Function        : Usage
5135
#
5136
# Description     : Display program usage information
5137
#
5138
# Inputs          : args            - Text message to display
5139
#
5140
#                   $opt_help       - Level of verbose ness
5141
#
5142
# Returns         : Does not return
5143
#                   This function will exit
5144
#
5145
sub Usage
5146
{
5147
    my( $msg ) = @_;
5148
    my %usage_args;
5149
 
5150
    #
5151
    #   Create a hash of arguments for the pod2usage function
5152
    #
5153
    $usage_args{'-input'} = __FILE__;
5154
    $usage_args{'-exitval'} = 42;
5155
    $usage_args{'-message'} = "\nbuildlib $msg\n" if $msg;
5156
    $usage_args{'-verbose'} = $opt_help < 3 ? $opt_help - 1 : 3 if ( $opt_help );
5157
 
5158
    #
5159
    #   Generate nice help
5160
    #
5161
    pod2usage(\%usage_args);
5162
}
5163
 
5164
#-------------------------------------------------------------------------------
5165
#   Documentation
5166
#
5167
 
5168
=pod
5169
 
361 dpurdie 5170
=for htmltoc    JATS::build
5171
 
227 dpurdie 5172
=head1 NAME
5173
 
361 dpurdie 5174
build - Build Environment and Makefiles
227 dpurdie 5175
 
5176
=head1 SYNOPSIS
5177
 
5178
jats build [options] [command]
5179
 
5180
     [perl buildlib.pl [options] PWD [command]]
5181
 
5182
 Options:
7296 dpurdie 5183
    -help           - Display terse usage
5184
    -help -help     - Display verbose usage
5185
    -man            - Display internal manual
5186
    -verbose[=n]    - Set level of progress verbosity
5187
    -debug[=n]      - Set the debug level
5188
    -cache          - Cache packages in the local dpkg_package cache
5189
    -localcache     - Cache packages into the interface directory
5190
    -cache -cache   - Forced refresh dependent packages in the local cache
5191
    -package        - Ignore packages that are not available and continue
5192
    -nopackages     - Ignore package processing directives
5193
    -forcebuildpkg  - Treat LinkPkgArchive directives as BuildPkgArchive
5194
                      Also suppress the use of symlinks so that the physical
5195
                      file will be copied locally.
5196
    -[no]force      - Force build even if build.pl is not newer
5197
                      Default: -force
5198
    -[no]generic    - Build system sanity test
5199
                      Default: Do not test
5200
    -buildinfo=path - Specify name of the buildinfo file
227 dpurdie 5201
 
5202
 Sticky settings:
331 dpurdie 5203
    -all           - Build for all platforms ignoring GBE_BUILDFILTER
5204
    -expert[=n]    - Relaxing dependency checks on the user makefiles
227 dpurdie 5205
 
5206
 Commands:
2078 dpurdie 5207
    clobber        - Remove generated build system (eg Makefiles).
6133 dpurdie 5208
    interface      - Only (re)build the interface tree.
361 dpurdie 5209
    rootonly       - Only (re)build the root directory.
7296 dpurdie 5210
    buildinfo      - Only generate build system info.
227 dpurdie 5211
 
5212
=head1 OPTIONS
5213
 
5214
=over 8
5215
 
331 dpurdie 5216
=item B<-help>
227 dpurdie 5217
 
5218
Print a brief help message and exits.
5219
 
5220
=item B<-help -help>
5221
 
5222
Print a detailed help message with an explanation for each option.
5223
 
5224
=item B<-man>
5225
 
5226
Prints the manual page and exits.
5227
 
331 dpurdie 5228
=item B<-verbose[=n]>
227 dpurdie 5229
 
261 dpurdie 5230
Increases program output.
227 dpurdie 5231
 
261 dpurdie 5232
If an argument is provided, then it will be used to set the level, otherwise the
5233
existing level will be incremented. This option may be specified multiple times.
227 dpurdie 5234
 
261 dpurdie 5235
=item B<-debug>
5236
 
227 dpurdie 5237
Increases program output. Enable internal debugging messages to generate detailed
5238
progress information.
5239
 
261 dpurdie 5240
If an argument is provided, then it will be used to set the level, otherwise the
5241
existing level will be incremented. This option may be specified multiple times.
5242
 
331 dpurdie 5243
=item B<-cache>
227 dpurdie 5244
 
6619 dpurdie 5245
This option will cause dependent packages to be cached in the users local
5246
dpkg_archive cache as defined via GBE_DPKG_CACHE
227 dpurdie 5247
 
5248
If the option is used twice then the packages will be forcibly refreshed.
5249
 
6619 dpurdie 5250
=item B<-localcache>
5251
 
5252
This option will cause dependent packages to be cached into the interface 
5253
directory. This option simplifies the use of a cache when building single
5254
packages.
5255
 
5256
If the option is used twice then the packages will be forcibly refreshed.
5257
 
331 dpurdie 5258
=item B<-package>
227 dpurdie 5259
 
5260
This option will cause the build process to ignore packages that cannot be
5261
located. The package build may fail at a later stage.
5262
 
5263
This option is used by the Auto Build Tool to handle packages that may not be
5264
needed in all builds.
5265
 
2078 dpurdie 5266
=item B<-nopackage>
5267
 
5268
This options will cause all the directives that process external packages to be
5269
ignored.
5270
 
5271
This directive has limited use. It can be used in conjunction with the
5272
'interface' build command in order to create Version Information files in a
5273
sandbox where the required packages do not yet exist.
5274
 
331 dpurdie 5275
=item B<-forcebuildpkg>
227 dpurdie 5276
 
5277
This option will force LinkPkgArchive directives to be treated as
5278
BuildPkgArchive directives. The result is that the 'interface' directory will be
5279
populated with the contents of all dependent packages. Moreover, on a Unix
5280
machine, the files will be copied and not referenced with a soft link.
5281
 
5282
This may be useful for:
5283
 
5284
=over 8
5285
 
361 dpurdie 5286
=item *
227 dpurdie 5287
 
361 dpurdie 5288
Remote Development
227 dpurdie 5289
 
361 dpurdie 5290
=item *
227 dpurdie 5291
 
361 dpurdie 5292
Collecting header files for scanning
5293
 
5294
=item *
5295
 
5296
Local modification of files for test/debug/development
5297
 
227 dpurdie 5298
=back
5299
 
331 dpurdie 5300
=item B<-[no]force>
227 dpurdie 5301
 
331 dpurdie 5302
The '-noforce' option will only perform a build, if the build.pl file
363 dpurdie 5303
has been modified, or the buildfilter has changed, since the last build.
331 dpurdie 5304
 
363 dpurdie 5305
The default operation will always force a build.
331 dpurdie 5306
 
4778 dpurdie 5307
=item B<-[no]generic>
5308
 
5309
If used, this option will perform a sanity test on the build type. If set to 
5310
Generic then the build must be a GENERIC build. If set to noGeneric then the build
5311
must not be a GENERIC build.
5312
 
5313
The default is to not perform the test.
5314
 
5315
This option is intended to be used by the automated build system.
5316
 
7296 dpurdie 5317
=item B<-buildinfo>
5318
 
5319
This option is only used in conjunction with the 'buildinfo' command. It will specify 
5320
the path of a file to write the build information. The dafault value is 'BuildInfo.properties'.
5321
 
5322
This option, by itslef, will not invoke the buildinfo mode.
5323
 
331 dpurdie 5324
=item B<-all>
5325
 
227 dpurdie 5326
This option will cause the build process to generate makefiles for all
5327
possible build targets ignoring the use of GBE_BUILDFILTER.
5328
 
5329
This option is sticky. Once used in a build it will be retained when makefiles
5330
are rebuilt.
5331
 
331 dpurdie 5332
=item B<-expert[=n]>
227 dpurdie 5333
 
5334
This option causes the generation of makefiles with relaxed dependancy checks.
5335
 
261 dpurdie 5336
If an argument is provided, then it will be used to set the level, otherwise a
5337
level of '1' will be set.
5338
 
227 dpurdie 5339
The makefiles will have no dependancy between the makefiles and the JATS build
5340
files or the users makefile. If the user's makefile.pl is changed then JATS
5341
will not detect the change and will not rebuild the makefiles. The user manually
5342
force the rebuild with the command 'jats rebuild'.
5343
 
5344
This option should be used with care and with full knowledge of its impact.
5345
 
5346
This option is sticky. Once used in a build it will be retained when makefiles
363 dpurdie 5347
are rebuilt. It will only be lost when the next 'jats build' is performed.
227 dpurdie 5348
 
261 dpurdie 5349
The effect of the option can be changed when the makefiles are processed. This
5350
option simply sets the default' mode of operation.
5351
 
227 dpurdie 5352
=item B<interface>
5353
 
6133 dpurdie 5354
This command will only build, or rebuild, the 'interface' directory.
227 dpurdie 5355
 
261 dpurdie 5356
This command will not build, or rebuild, the root directory. The build
227 dpurdie 5357
process will not recurse through the subdirectories creating makefiles.
5358
 
261 dpurdie 5359
=item B<rootonly>
5360
 
6133 dpurdie 5361
This command will only build, or rebuild, the 'interface' directory and 
5362
the root-level makefiles.
261 dpurdie 5363
 
5364
The build process will not recurse through the subdirectories creating
5365
makefiles. These can be made on-demand by jats if a 'make' command is issued.
5366
 
7296 dpurdie 5367
 
5368
=item B<buildinfo>
5369
 
5370
This command is used by the build system to generate information about the
5371
build. It will create a file with the following information.
5372
 
5373
=over 4
5374
 
5375
=item * All platforms that the package can be built for.
5376
 
5377
=item * All platforms that the package will be built for with the current build filter
5378
 
5379
=item * Platforms that have been specifically excluded from the build
5380
 
5381
=item * Platforms not known to JATS
5382
 
5383
=item * Toolset build information
5384
 
5385
=item * Generic build information
5386
 
5387
=item * Indication of production and debug builds
5388
 
5389
=item * JAVA version specified
5390
 
5391
=back
5392
 
5393
 
5394
 
227 dpurdie 5395
=item B<clobber>
5396
 
5397
This command will remove generated build system files and directories.
5398
 
5399
=back
5400
 
5401
=head1 DESCRIPTION
5402
 
5403
The default build process will parse the user's build.pl file and create the
5404
'interface' directory before creating makefiles for each target platform.
5405
 
5406
The 'build' process simply generates the build sandbox. It does not invoke the
5407
generated makefiles. This must be done by the user in a different phase.
5408
 
5409
The 'build' process need only be invoked if the build.pl file has changed. The
5410
generated makefiles will detected changes to the makefile.pl's and cause them to
5411
be generated as required. The 'build' step sets up the sandboxes external
5412
environment.
5413
 
5414
=head1 INVOCATION
5415
 
5416
This perl library (buildlib.pl) is not designed to be invoked directly by the
5417
user. It should be invoked through a 'build.pl' file. Moreover, for historical
5418
reasons, the build.pl is not easily invoked. It is best to only invoke the
5419
'build' process via the JATS wrapper scripts : jats.bat or jats.sh.
5420
 
331 dpurdie 5421
The build.pl file must be invoked with one fixed arguments, followed by user
227 dpurdie 5422
options and subcommands
5423
 
5424
=over 8
5425
 
361 dpurdie 5426
=item   1
227 dpurdie 5427
 
361 dpurdie 5428
The current working directory
5429
 
227 dpurdie 5430
This could have been derived directly by the program, rather than having it
5431
passed in.
5432
 
361 dpurdie 5433
=item   2
227 dpurdie 5434
 
361 dpurdie 5435
Options and commands may follow the first two mandatory arguments.
5436
 
227 dpurdie 5437
=back
5438
 
5439
The build.pl file must 'require' the buildlib.pl and makelib.pl. The preferred
5440
code is:
5441
 
5442
=over 8
5443
 
5444
    build.pl: First statements
5445
    $MAKELIB_PL     = "$ENV{ GBE_TOOLS }/makelib.pl";
5446
    $BUILDLIB_PL    = "$ENV{ GBE_TOOLS }/buildlib.pl";
5447
 
5448
    require         "$BUILDLIB_PL";
5449
    require         "$MAKELIB_PL";
5450
 
5451
=back
5452
 
5453
=cut
5454
 
5455
1;