Subversion Repositories DevTools

Rev

Rev 7441 | Go to most recent revision | 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
        #
2309
        #   If we are playing in a sandbox, then the version number is
2310
        #   not used. The Package suffix is still used so that we can
2311
        #   differentiate sysbasetypes.xxxxx.mas and sysbasetypes.xxxxx.syd
2312
        #
2313
        if ( $sandbox )
2314
        {
359 dpurdie 2315
            my ($pn, $pv, $ps ) = SplitPackage ($name, $uversion );
227 dpurdie 2316
            $version = 'sandbox';
2317
            $version .= '.' . $ps if ( $ps );
2318
        }
2319
        else
2320
        {
2321
            $version = $uversion;
2322
        }
2323
 
6133 dpurdie 2324
        $pkg = "$dpkg/$name/$version";
2325
        $pkg = "$dpkg/$name/$version.lnk"
2326
            if ( -e "$dpkg/$name/$version.lnk" );
2327
 
227 dpurdie 2328
        #
2329
        #   Using a soft link
2330
        #   Emulate a link in software. The link file contains one line
2331
        #   which is the real pathname of the package
2332
        #
2333
        if ( $pkg =~ m~(.*)\.lnk$~  )
2334
        {
2335
            #
2336
            #   Warn the user if both a link and a real directory
2337
            #   are both present - the link may well be incorrect
2338
            #
2339
            my $non_link = $1;
2340
            Warning ("Suspect package link: $pkg",
2341
                     "Both a link and a package where found - using the link" )
2342
                                                            if ( -d $non_link );
2343
 
2344
            Debug( "           link found -> $pkg" );
2345
            my $link_src = $pkg;
6133 dpurdie 2346
            $pkg = TagFileRead($pkg);
2347
            $pkg =~ s~\\~/~g;
5819 dpurdie 2348
            if ($pkg =~ s~^GBE_SANDBOX/~$::GBE_SANDBOX/~)
2349
            {
6133 dpurdie 2350
                    $pkgFromSandbox++;
2351
 
5819 dpurdie 2352
                    # If the target sandbox is in the 'deploymode' then the package
2353
                    # will not be in the expected location. It will be in a 'build/deploy'
2354
                    # subdir. Remove the pkg/name dir to get to the root of the package
2355
                    my @dirs = File::Spec->splitdir( $pkg );
2356
                    splice(@dirs, -2);
2357
                    my $deployBox = catdir(@dirs, 'build', 'deploy');
2358
                    $pkg = $deployBox if ( -d $deployBox);
2359
            }
227 dpurdie 2360
 
2078 dpurdie 2361
            unless ( -d $pkg )
2362
            {
2363
                Error ("Broken link: $pkg",
2364
                       "Source link: $link_src",
2365
                       "Try deleting the .lnk file" ) unless ( $NoPackageError );
2366
 
2367
                Warning ("Package not available. Broken link: $pkg");
2368
            }
227 dpurdie 2369
        }
2370
 
2371
        Debug( "           searching $pkg" );
2372
 
2373
        #   Does the package directory exist?
2374
        #   Terminate the directory name with a "/" to detect hidden spaces
2375
        #..
2376
        $pkg =~ s~//~/~g;
2377
        next unless ( -d "$pkg/" );             # exists ?
2378
 
2379
        #
2380
        #   If the package exists within the dpkg_archive cache then mark the
2381
        #   version as having been used. Used by cache cleanup algorithms
2382
        #
2383
        if ( $isa_cache  )
2384
        {
2385
            TouchFile ( "$pkg/used.cache", "Marks the cache copy as being used");
6619 dpurdie 2386
            #print( "                  Cached -> $pkg\n" );
227 dpurdie 2387
        }
2388
 
2389
        #
2390
        #   Use the first suitable package found
2391
        #..
2392
 
2393
        Debug( "           importing $pkg" );
2394
        return $pkg, $local;
2395
    }
2396
 
2397
    #
2398
    #   Package not found
2399
    #   This is an error, although it can be bypassed
2400
    #
261 dpurdie 2401
    Error ("Required package not found: '$name/$version'" ) unless ( $NoPackageError );
227 dpurdie 2402
 
261 dpurdie 2403
    Log( "WARNING .... Package not available: '$name/$version'" );
283 dpurdie 2404
    return;
227 dpurdie 2405
}
2406
 
2407
 
2408
#-------------------------------------------------------------------------------
2409
# Function        : LinkEntry
2410
#
6504 dpurdie 2411
# Description     : Scan a package and locate platform specific directories
227 dpurdie 2412
#                   Create data structures to capture the information
6276 dpurdie 2413
#                   This function is used by LinkPkgArchive
227 dpurdie 2414
#                   to perfom the bulk of package inclusion work.
2415
#
6276 dpurdie 2416
# Inputs          : $platform   - Platform being processed
2417
#                   $entry      - Reference to a PackageEntry
227 dpurdie 2418
#
2419
sub LinkEntry
2420
{
6276 dpurdie 2421
    my( $platform, $base_entry ) = @_;
227 dpurdie 2422
 
2423
    #
6276 dpurdie 2424
    #   Clone the entry - we will add platform specific data into it
2425
    #
2426
    my $entry = dclone($base_entry);
227 dpurdie 2427
 
6276 dpurdie 2428
 
227 dpurdie 2429
    #   Populate includes:
2430
    #
2431
    #   - include/$platform                 (eg include/solaris)
2432
    #   - inc/$platform                     (eg inc/solaris)
2433
    #   - include.$platform                 (eg include.solaris)
2434
    #   - inc.$platform                     (eg inc.solaris)
2435
    #   - include                           (eg include)
2436
    #   - inc                               (eg inc)
2437
    #
2438
    #   plus, product specialisation directores
2439
    #
2440
    #   eg. BuildProduct( 'IDFC', 'WIN32' );
2441
    #
2442
    #   - inc/IDFC_WIN32                    <- derived platform
2443
    #   - inc/IDFC                          <- product
2444
    #   - inc/WIN32                         <- target
2445
    #..
2446
    my $parts = $BUILDINFO{$platform}{PARTS};
2447
 
2448
    foreach my $part ( @$parts )
2449
    {
6276 dpurdie 2450
        $entry->RuleInc( "/include." . $part );
2451
        $entry->RuleInc( "/inc." . $part );
2452
        $entry->RuleInc( "/include/" . $part );
227 dpurdie 2453
        $entry->RuleInc( "/inc/" . $part );
2454
    }
2455
 
2456
    #
2457
    #   Also search the root include directory - last
2458
    #
6276 dpurdie 2459
    $entry->RuleInc( "/include" );
227 dpurdie 2460
    $entry->RuleInc( "/inc" );
2461
 
2462
    #   Populate libraries:
2463
    #
2464
    #   - lib/lib.$platform[D|P]            (eg lib/lib.sparcD)
2465
    #   - lib/$platform[D|P]                (eg lib/lib.sparc)
2466
    #   - lib.$platform[D|P]                (eg lib.sparcD)
2467
    #
2468
    #   plus, product specialisation directores
2469
    #
2470
    #   eg. BuildProduct( 'IDFC', 'WIN32' );
2471
    #
2472
    #   - lib/IDFC_WIN32                    <- derived platform
2473
    #   - lib/IDFC                          <- product
2474
    #   - lib/WIN32                         <- target
2475
    #..
2476
    $parts = $BUILDINFO{$platform}{PARTS};
2477
 
2478
    foreach my $part ( @$parts )
2479
    {
6276 dpurdie 2480
        $entry->RuleLib("/lib" . ".$part" );
2481
        $entry->RuleLib("/lib" . "/lib.$part" );
227 dpurdie 2482
        $entry->RuleLib("/lib" . "/$part" );
2483
    }
2484
 
2485
    #
2486
    #   Some extra places to search
2487
    #   None. This is good as it indicates that all locations are described in PARTS
2488
    #
2489
    #   Do NOT search in /lib. There are no libraries that work on all platforms
2490
    #   Libraries are binaries!
2491
    #
2492
    #    $entry->RuleLib( "/lib" );
2493
 
2494
    #   Tools:
2495
    #
2496
    #   Tools provide an extensible search path for tools and
2497
    #   utilities used to build programs. These are tools that
2498
    #   are executable on the current host machine and are
2499
    #   independent of the toolset.
2500
    #
2501
    #..
2502
    $entry->ExamineToolPath();
2503
    $entry->ExamineThxPath($platform);
2504
    $entry->Cleanup();                          # cleanup tables
2505
 
2506
    #
2507
    #   Add the package entry to the array of such entries for
2508
    #   the current platform. Maintain the discovery order
2509
    #
2510
    #..
2511
    push ( @{$PKGRULES{$platform}}, $entry );
2512
}
2513
 
2514
 
2515
#-------------------------------------------------------------------------------
2516
# Function        : BuildPkgArchive
2517
#
2518
# Description     : Include an external package into the build sandbox
2519
#                   by copying the packages files into the interface directory
2520
#
2521
# Inputs          : package name
2522
#                   package version
2523
#
2524
sub BuildPkgArchive
2525
{
2526
    my( $name, $version ) = @_;
2527
 
2528
    return if ( $Clobber );                     # clobber mode ?
2529
 
2530
    Debug( "BuildPkgArchive:" );
2531
    Debug( "Name:      $name" );
2532
    Debug( "Version:   $version" );
2533
 
2534
    DataDirective("BuildPkgArchive");           # This directive allowed here
2535
 
2078 dpurdie 2536
    if ( $IgnorePkgs )
2537
    {
2538
        Log( "BuildPkgArchive . $name ($version) - Ignored" );
2539
        return;
2540
    }
2541
 
227 dpurdie 2542
    #
2543
    #   Ensure that we have do not have multiple definitions
2544
    #
2545
    if ( PackageEntry::Exists( $name, $version ) )
2546
    {
261 dpurdie 2547
        Log( "Duplicate Package: $name, $version. Duplicate entry ignored" );
227 dpurdie 2548
        return;
2549
    }
2550
 
2551
    if ( $Cache && $::GBE_DPKG_CACHE )
2552
    {
2553
        my $mode = ($Cache > 1) ? "-refresh" : "";
261 dpurdie 2554
        Log( "BuildPkgArchive . $name ($version) Update Cache" );
5744 dpurdie 2555
        System('--NoExit', "$::GBE_PERL $::GBE_TOOLS/cache_dpkg.pl $mode -wait -quiet $name/$version" );
227 dpurdie 2556
    }
2557
 
2558
    #
2559
    #   Locate the package
6133 dpurdie 2560
    #   Use the first instance of the package that is found
227 dpurdie 2561
    #
261 dpurdie 2562
    Log( "BuildPkgArchive . $name ($version)" );
6276 dpurdie 2563
    my ( $pkg, $local, $pkgSig ) = PackageLocate( $name, $version );
227 dpurdie 2564
    if ( $pkg )
2565
    {
2566
        #
2567
        #   Create a Package Entry
2568
        #
6276 dpurdie 2569
        my $entry = PackageEntry::New( $pkg, $name, $version, 'build', $local, $pkgSig );
227 dpurdie 2570
 
2571
        #
2572
        #   Determine if the package needs to be installed:
2573
        #       If the package is a 'local' package then force transfer
2574
        #       If the user has specified --cache then force transfer
2575
        #       If package is newer that copy, then force transfer
2576
        #       If copy does not exist, then force a transfer
2577
        #
6276 dpurdie 2578
        my $tag_dir = "$CwdFull/$BUILDINTERFACE/BuildTags";
227 dpurdie 2579
        my $tag_file = "$tag_dir/${name}_${version}.tag";
6073 dpurdie 2580
        my $arglist = GenerateInstallArgumentList();
227 dpurdie 2581
 
2582
        my $package_installed;
2583
        $package_installed = 1
2584
            if ( !$local &&
2585
                 !$Cache &&
6073 dpurdie 2586
                 !FileIsNewer( $entry->GetBaseDir('descpkg'), $tag_file ) &&
2587
                 TagFileMatch( $tag_file, $arglist)
2588
                  );
227 dpurdie 2589
 
2590
        #
2591
        #   Determine the package format and use the appropriate installer
2592
        #   Supported formats
6133 dpurdie 2593
        #       1) Package has a descpkg file (only style currently supported)
227 dpurdie 2594
        #
2595
        if ( $package_installed ) {
2596
            Verbose ("Package already installed: $name, $version");
2597
 
2598
        } else {
261 dpurdie 2599
            Log( "                . installing '$pkg'" );
2600
            Log( "                . -> " . readlink($pkg) ) if ( -l $pkg );
227 dpurdie 2601
 
2602
            if ( -e "$pkg/descpkg" )
2603
            {
2604
 
2605
                #
2606
                #   If forcing a BuildPkg, then don't use symlinks
2607
                #   to files in dpkg_archive
2608
                #
331 dpurdie 2609
                my @opts;
2610
                push @opts, "--NoSymlinks" if ( $ForceBuildPkg );
2611
                push @opts, "--AllowOverWrite" if ( $local );
227 dpurdie 2612
 
2613
                #
2614
                #   Determine all the Platforms, Products and Targets
2615
                #   that need to be installed
2616
                #
6073 dpurdie 2617
 
6276 dpurdie 2618
                System( "cd $pkg; $::GBE_PERL $::GBE_TOOLS/installpkg.pl $CwdFull/$BUILDINTERFACE $CwdFull @opts $arglist");
227 dpurdie 2619
                Error( "Package installation error" ) if ( $? != 0 );
2620
            }
2621
            else
2622
            {
2623
                Error ("Unknown package format for package $name/$version found in $pkg");
2624
            }
2625
 
2626
            #
2627
            #   Tag the package as installed - after it has been transferred
2628
            #
2629
            mkdir ( $tag_dir );
6073 dpurdie 2630
            FileCreate( $tag_file, $arglist );
227 dpurdie 2631
        }
2632
 
2633
        #
2634
        #   Process package
2635
        #
2636
        IncludePkg ( $name, $pkg );
2637
 
2638
        #
2639
        #   Complete the creation of the package entry
2640
        #   Add the information for all platforms
2641
        #
2642
        $entry->Cleanup();
2643
        for my $platform (@BUILD_ACTIVEPLATFORMS)
2644
        {
2645
            $entry->ExamineToolPath();
2646
            $entry->ExamineThxPath($platform);
2647
            push ( @{$PKGRULES{$platform}}, $entry );
2648
        }
2649
    }
2650
}
2651
 
2652
#-------------------------------------------------------------------------------
6684 dpurdie 2653
# Function        : LinkPkgExclude 
2654
#
2655
# Description     : Mark a package to be excluded / included for a specific build
2656
#                   Intended use:
2657
#                       Recover from really (reaaly) badly constructed packages
2658
#                       
2659
#                   Essentially this directive will 'Exclude' packages from the
2660
#                   a specific build target (platform) by removing it from data
2661
#                   structures that are exported to the make stage
2662
#                   
2663
#                   Process ONLY works for LinkPkgArchive packages
2664
#
2665
# Inputs          : platform-selector   - A JATS style platform specifier
2666
#                   package-list        - one or or packages to process
2667
#                   
2668
# Example         : LinkPkgExclude('!SK100', 'PulseSdk');
2669
#                   LinkPkgExclude('SK100' , 'crypto');
2670
#
2671
sub LinkPkgExclude
2672
{
2673
    DataDirective('LinkPkgExclude');
2674
    Error("LinkPkgExclude(@_) requires at least two arguments") unless ((scalar @_) >= 2);
2675
    #
2676
    #   Simply save the arguments for later processing
2677
    #
2678
    push @LINKPKGEXLUDES, join($;, @_);
2679
}
2680
 
2681
#-------------------------------------------------------------------------------
2682
# Function        : ProcessLinkPkgExclude 
2683
#
2684
# Description     : INTERNAL Function
2685
#                   Process the data collected by the LinkPkgExclude directives  
2686
#
2687
# Inputs          : None
2688
#                   Uses: LINKPKGEXLUDES    
2689
#
2690
# Returns         : Will modify interal classes and data structures
2691
#
2692
sub ProcessLinkPkgExclude
2693
{
2694
    my @unknownPlatforms;
2695
    my @unknownPkg;
2696
    my @notLinkPkg;
2697
 
2698
    #
2699
    #   Create a hash of known platforms - detect and report bad user input
2700
    #
2701
    my %fullPlatformList =  map { $_ => 1 } @BUILDPLATFORMS;
2702
 
2703
    #
2704
    #   Process each directive
2705
    #
2706
    foreach ( @LINKPKGEXLUDES )
2707
    {
2708
        my (@add, @remove);
2709
        my ($pSel, @pkgList) = split($;, $_);
2710
        Log("LinkPkgExclude $pSel, @pkgList");
2711
 
2712
 
2713
        #
2714
        #   Process the selector in the same manor as makefiles
2715
        #       Need the selector to be active
2716
        #       Selector may be an alias or a platform
2717
        #       Selector may be negated
2718
        #       Selectors are comma seperated
2719
        #       Additive elements are processed before subtactive elements
2720
        #           
2721
        my @pItems = split(/\s*,\s*/, $pSel);
2722
        @pItems = ExpandPlatforms( @pItems );
2723
 
2724
         foreach my $platform ( @pItems) {
2725
             my $pname = $platform;
2726
             my $invert;
2727
 
2728
             if (substr($platform, 0, 1) eq '!') {
2729
                 $invert = 1;
2730
                 $pname = substr($platform, 1)
2731
                 }
2732
 
2733
             unless (exists($fullPlatformList{$pname})) {
2734
                 UniquePush(\@unknownPlatforms, $pname);
2735
                 next;
2736
                 }
2737
 
2738
             if ( $invert )  {
2739
                 push @remove, $pname; 
2740
             } else {
2741
                 push @add, $pname; 
2742
             }
2743
         }
2744
 
2745
         #
2746
         #   Build complete list of allowed platforms
2747
         #       Process additive rules before removal rules
2748
         #       If there are no additive rules, then assume all protaforms
2749
         #
2750
         my %calcList;
2751
         @add = @BUILDPLATFORMS unless @add;
2752
         $calcList{uc $_} = 1 foreach (@add);
2753
         delete $calcList{uc $_} foreach (@remove);
2754
         Verbose2("LinkPkgExclude ", keys %calcList,",", @pkgList);
2755
 
2756
         #
2757
         #  Now have a list of platforms to process (exclude)
2758
         #  Now have a list of packages to exclude
2759
         #
2760
         #  Iterate over the package rules and mark those to be excluded
2761
         #
2762
         foreach my $platform ( keys %calcList )
2763
         {
2764
             unless (exists($PKGRULES{$platform})) {
2765
                 next;
2766
             }
2767
 
2768
             foreach my $ePackage (@pkgList) {
2769
                 my $pkgFound;
2770
                 foreach my $package ( @{$PKGRULES{$platform}} )
2771
                 {
2772
                     my $fname = $package->{'dname'};
2773
                     if ( $package->{'dproj'}) {
2774
                         $fname .= '.' . $package->{'dproj'};
2775
                     }
2776
 
2777
                     if ( $ePackage eq $package->{'dname'}  || $ePackage eq $fname) {
2778
                         $pkgFound = 1;
2779
 
2780
                         if ($package->{'type'} ne 'link') {
2781
                             UniquePush(\@notLinkPkg, $ePackage);
2782
                             last;
2783
                         }
2784
 
2785
                         $package->{'EXCLUDE'} = 1;
2786
                         Debug("Exclude", $platform, $fname );
2787
                         last;
2788
                     }
2789
                 }
2790
                 UniquePush(\@unknownPkg, $ePackage) unless $pkgFound;
2791
             }
2792
         }
2793
   }
2794
 
2795
    ReportError("LinkPkgExclude. Unknown platforms:", @unknownPlatforms) if @unknownPlatforms;
2796
    ReportError("LinkPkgExclude. Unknown packages:", @unknownPkg) if @unknownPkg;
2797
    ReportError("LinkPkgExclude. BuildPkgArchive not allowed for:", @notLinkPkg) if @notLinkPkg;
2798
    ErrorDoExit();
2799
}
2800
 
2801
#-------------------------------------------------------------------------------
311 dpurdie 2802
# Function        : CreateInterfacePackage
2803
#
2804
# Description     : Create a dummy package entry to describe the Interface
2805
#                   This is done AFTER all the BuildPkgArchive directives have
2806
#                   been processed so that the interface directory is fully
2807
#                   processed
2808
#
2809
# Inputs          : None
2810
#
2811
# Returns         : 
2812
#
2813
sub CreateInterfacePackage
2814
{
2815
    foreach my $platform ( @BUILD_ACTIVEPLATFORMS )
2816
    {
6276 dpurdie 2817
        my $entry = PackageEntry::Interface( "$CwdFull/$BUILDINTERFACE" );
311 dpurdie 2818
 
2819
        #
2820
        #   Locate include and lib bits within the interface
2821
        #   This is much simpler than for a LinkPkgArchive as the form
2822
        #   has been sanitized
2823
        #
2824
        my $parts = $BUILDINFO{$platform}{PARTS};
2825
 
2826
        foreach my $part ( @$parts )
2827
        {
2828
            $entry->RuleInc( "/include/" . $part );
2829
        }
2830
        $entry->RuleInc( "/include" );
2831
 
2832
        foreach my $part ( @$parts )
2833
        {
2834
            $entry->RuleLib("/lib/" . $part );
2835
        }
2836
 
2837
        $entry->ExamineToolPath();
2838
        $entry->ExamineThxPath($platform);
2839
        $entry->Cleanup();
2840
 
2841
        #
2842
        #   Add the package entry to the array of such entries for
2843
        #   the current platform. Force it to be the first one as
2844
        #   the interface directory will be scanned first
2845
        #
2846
        unshift ( @{$PKGRULES{$platform}}, $entry );
2847
    }
2848
}
2849
 
2850
#-------------------------------------------------------------------------------
227 dpurdie 2851
# Function        : GenerateInstallArgumentList
2852
#
2853
# Description     : Generate an argument list for the installpkg.pl script
2854
#                   The argument list is of the form
2855
#                       --Platform:xx[:xx[:xx]] --Platform:yy[:yy[:yy]] ...
2856
#                   Where xx is:
2857
#                       * a 'part' of the target platform
2858
#                         Order is: platform, product, ...  target( in that order )
2859
#                       * --Option[=yyy]
2860
#                        An option to be passed to the script. These are bound only
2861
#                        to the enclosed platform.
2862
# Inputs          :
2863
#
2864
# Returns         : See above
2865
#
2866
sub GenerateInstallArgumentList
2867
{
2868
    my @arglist;
2869
 
2870
    #
2871
    #   Generate the argument list as an array
2872
    #
2873
    for (@BUILD_ACTIVEPLATFORMS)
2874
    {
2875
        my @args = '--Platform';
2876
        push @args, @{$BUILDINFO{$_}{PARTS}};
2877
        push @arglist, join (":" , @args );
2878
    }
2879
 
2880
    return "@arglist";
2881
}
2882
 
2883
#-------------------------------------------------------------------------------
2884
# Function        : GeneratePlatformList
2885
#
2886
# Description     : Return a list of platforms that should particiate in this
2887
#                   build. This is a function of
2888
#                       1) Platforms defined in the build.pl file
5679 dpurdie 2889
#                       2) Platforms excluded in the build.pl file
2890
#                       3) User filter defined in GBE_BUILDFILTER
227 dpurdie 2891
#
2892
#                   The primary use of this function is to limit the creation
2893
#                   of makefiles to those that have supported compilers on
2894
#                   the underlying machine.
2895
#
2896
#                   GBE_BUILDFILTER is a space seperated string of words
2897
#                   Each word may be one of
2898
#                       OPTION=TAG or OPTION=!TAG
2899
#                       TAG or !TAG. This is the same as --TARGET=TAG
2900
#
2901
#                   Bare tags are taken to be TARGETS.
2902
#
2903
#                   Where OPTION may be one of
2904
#                       --PLATFORM
2905
#                       --PRODUCT
2906
#                       --TARGET
5679 dpurdie 2907
#                   For a BuildProduct( AA,BB,CC)
2908
#                       Product     - AA
2909
#                       Targets     - BB, CC
2910
#                       Platforms   - AA_BB, AA_CC
227 dpurdie 2911
#
2912
#                   Special cases
2913
#                   1) If GBE_BUILDFILTER is empty, then all available platforms are used
2914
#                      The global $All is set, then all available platforms are used
2915
#                   2) If the first word of GBE_BUILDFILTER is a negative filter,
2916
#                      ie is used the !xxxx or yyy=!xxxx construct, then it is assumed
2917
#                      that the filter will start with all available platforms
2918
#                   3) The special word --ALL forces selection of ALL platforms
2919
#                      and may reset any existing scanning
2920
#                   4) GBE_BUILDFILTER is parsed left to right. It is possible to add and
2921
#                      subtract items from the list.
2922
#                   5) OPTIONS are case insensitive
2923
#                      TAGS are case sensitive
2924
#
2925
#
2926
# Inputs          : GBE_BUILDFILTER from the environment
2927
#
2928
# Returns         : An array of platforms to include in the build
2929
#                   Maintains @BUILD_ACTIVEPLATFORMS  - the last calculated result
2930
#                   Ensures that @DEFBUILDPLATFORMS is a subset of @BUILD_ACTIVEPLATFORMS
6276 dpurdie 2931
#                   Rebuilds BUILDPLATFORMS to ensure that excluded platforms are not present
227 dpurdie 2932
#
2933
sub GeneratePlatformList
2934
{
2935
    #
2936
    #   Return the cached result for speed
2937
    #   The value need only be calculated once
2938
    #
2931 dpurdie 2939
    unless ( @BUILD_ACTIVEPLATFORMS )
227 dpurdie 2940
    {
2941
        my ($platform_filter);
2942
        my %result;
2943
        my %part_to_platform;
6276 dpurdie 2944
        my @New_BUILDPLATFORMS = ();
227 dpurdie 2945
 
2946
        #
2947
        #   Create a data structure to assist in the production of the platform list
2948
        #   The structure will be a hash of hashes of arrays
2949
        #
2950
        #   The first level hash will be keyed by the word TARGET, PRODUCT or PLATFORM
2951
        #   The second level of the hash will keyed by available targets, products or platforms
2952
        #   The value of the field will be an array of platforms that match the keyword
2953
        #
2954
        for my $platform (keys (%::BUILDINFO))
2955
        {
2956
            my $pParts = $::BUILDINFO{$platform};
2957
 
2958
            #
6276 dpurdie 2959
            #   Include into New_BUILDPLATFORMS 
2960
            #
2961
            if ($pParts->{NOT_AVAILABLE} <= 1) {
2962
                push @New_BUILDPLATFORMS, $platform;
2963
            }
2964
 
2965
            #
227 dpurdie 2966
            #   Skip platforms that are known to be unavailable on this build
2967
            #   machine. Self configure
2968
            #
2969
            next if ( $pParts->{NOT_AVAILABLE} );
2970
 
2971
            my $target  = $pParts->{TARGET};
2972
            my $product = $pParts->{PRODUCT};
2973
 
2974
            push @{$part_to_platform{'PLATFORM'}{$platform}}, $platform;
2975
            push @{$part_to_platform{'TARGET'}  {$target}}  , $platform;
2976
            push @{$part_to_platform{'PRODUCT'} {$product}} , $platform;
2977
        }
2978
        #
2979
        #   Determine the source of the filter
2980
        #   If the user provides one, then use it.
2981
        #   Otherwise its taken from the environment.
2982
        #
2983
        #   Global build all platforms - Kill any user filter
2984
        #
2985
        if ( $All )
2986
        {
2987
            $platform_filter = "";
2988
        }
2989
        else
2990
        {
2991
            $platform_filter = "";
6276 dpurdie 2992
            $platform_filter = uc $::GBE_BUILDFILTER
227 dpurdie 2993
                if ( defined($::GBE_BUILDFILTER) );
2994
        }
2995
        Debug( "GeneratePlatformList: Filter:$platform_filter" );
2996
 
2997
        #
2998
        #   Detect the special cases
5679 dpurdie 2999
        #       1) No user definition
227 dpurdie 3000
        #       2) First word contains a subtractive element
5679 dpurdie 3001
        #   And assume all platforms    
227 dpurdie 3002
        #
3003
        my (@filter) = split( ' ', $platform_filter );
3004
 
3005
        if ( !scalar @filter || $filter[0] =~ m/^$/ || $filter[0] =~ m/!/ )
3006
        {
3007
            %result = %{$part_to_platform{'PLATFORM'}}
3008
                if exists $part_to_platform{'PLATFORM'} ;
3009
        }
5679 dpurdie 3010
 
6276 dpurdie 3011
        #
3012
        # Add GENERIC platforms to the platform filter, if available
3013
        #
3014
        if (exists $part_to_platform{'PLATFORM'})
3015
        {
3016
            foreach my $platform( 'GENERIC', 'GENERIC_' . uc($::GBE_MACHTYPE) )
3017
            {
3018
                $result{$platform} = 1 if (exists $part_to_platform{'PLATFORM'}{$platform}) 
3019
            }
3020
        }
3021
 
227 dpurdie 3022
#DebugDumpData( "PartToPlatform", \%part_to_platform );
6276 dpurdie 3023
#DebugDumpData("Result", \%result);
227 dpurdie 3024
 
3025
        #
3026
        #   Process each element in the user filter list
3027
        #   Expand platforms into known aliases
3028
        #
3029
        for my $word (@filter)
3030
        {
3031
            my $platform;
3032
 
3033
            if ( $word =~ m/^--ALL/i )
3034
            {
3035
                %result = %{$part_to_platform{'PLATFORM'}};
3036
            }
3037
            elsif ( $word =~ m/^--(TARGET)=(!?)(.*)/i ||
3038
                    $word =~ m/^--(PRODUCT)=(!?)(.*)/i ||
3039
                    $word =~ m/^--(PLATFORM)=(!?)(.*)/i ||
3040
                    ( $word !~ m/^-/ && $word =~ m/()(!?)(.*)/ )
3041
                )
3042
            {
3043
                my $table = uc($1);
3044
                $table = "TARGET"
3045
                    unless ( $1 );
3046
 
3047
                #
3048
                #   Expand PLATFORMs into known aliases
3049
                #   Alias will expand to PLATFORMs so it won't work unless we are
6133 dpurdie 3050
                #   processing PLATFORMs.
227 dpurdie 3051
                #
3052
                my @taglist = ( $table eq "PLATFORM" ) ? ExpandPlatforms($3) : $3;
3053
 
3054
                #
3055
                #   Add / Remove items from the result
3056
                #
3057
                for my $item ( @taglist )
3058
                {
3059
                    my $plist = $part_to_platform{$table}{$item};
3060
                    for ( @{$plist})
3061
                    {
6133 dpurdie 3062
                        if ( $2 ) {
227 dpurdie 3063
                            delete $result{$_};
6133 dpurdie 3064
                        } else {
227 dpurdie 3065
                            $result{$_} = 1;
3066
                        }
3067
                    }
3068
                }
3069
            }
3070
            else
3071
            {
3072
                print "GBE_BUILDFILTER filter term not understood: $word\n";
3073
            }
3074
        }
3075
 
3076
        #
3077
        #   Return an array of platforms to process
3078
        #
3079
        @BUILD_ACTIVEPLATFORMS = sort keys %result;
3080
 
3081
        #
3082
        #   Ensure that DEFBUILDPLATFORMS is a subset of build active platforms
3083
        #
3084
        my @NEW_DEFBUILDPLATFORMS;
3085
        foreach ( @DEFBUILDPLATFORMS )
3086
        {
3087
            push @NEW_DEFBUILDPLATFORMS, $_
3088
                if ( exists $result{$_} );
3089
        }
3090
        @DEFBUILDPLATFORMS = @NEW_DEFBUILDPLATFORMS;
6276 dpurdie 3091
 
3092
        #
3093
        #   Update BUILDPLATFORMS
3094
        #
3095
        @BUILDPLATFORMS = @New_BUILDPLATFORMS;
227 dpurdie 3096
    }
3097
 
3098
    Debug("GeneratePlatformList: Result:@BUILD_ACTIVEPLATFORMS");
3099
    return @BUILD_ACTIVEPLATFORMS;
3100
}
3101
 
3102
#-------------------------------------------------------------------------------
3103
# Function        : PrintPlatforms
3104
#
3105
# Description     : Petty print the specified platform list, breaking line
6276 dpurdie 3106
#                   on either a primary key change or length width >100.
227 dpurdie 3107
#
6276 dpurdie 3108
# Inputs          : $list           - Reference to an array
3109
#                   $nl             - New line stuff.
3110
#                                     Use to prefix new lines
227 dpurdie 3111
#
6276 dpurdie 3112
# Returns         : Formatted string
3113
#
227 dpurdie 3114
# Example Output :
3115
#
3116
#           DDU_LMOS_WIN32 DDU_LMOS_linux_armv4 DDU_LMOS_linux_i386
3117
#           IDFC_LMOS_WIN32 IDFC_LMOS_linux_armv4 IDFC_LMOS_linux_i386
3118
#           LMOS_WCEPSPC_ARM LMOS_WCEPSPC_EMU LMOS_WIN32 LMOS_linux_armv4
3119
#           LMOS_linux_i386
3120
#..
3121
sub PrintPlatforms
3122
{
3123
    my ($platforms, $nl) = @_;
6276 dpurdie 3124
    my ($string) = "";
3125
    my $maxLen = 100 - length($nl);
227 dpurdie 3126
 
2931 dpurdie 3127
    if ( @$platforms )
227 dpurdie 3128
    {
6276 dpurdie 3129
        my $line = "";
3130
        my $pel = "";
3131
        my $first = 1;
3132
        my $prefix = '';
3133
        foreach my $k ( sort @$platforms)
227 dpurdie 3134
        {
6276 dpurdie 3135
            my $k2 = substr($k, 0 , 2);
3136
            if (( $k2 ne $pel  || (length($line) + length ($k) > $maxLen) ) && (!$first)) {
3137
                $string .= $line;
3138
                $line = $nl;
3139
                $prefix = '';
227 dpurdie 3140
            }
6276 dpurdie 3141
            $line .= $prefix . $k;
3142
            $pel = $k2;
3143
            $first = 0;
3144
            $prefix = ' ';
227 dpurdie 3145
        }
6276 dpurdie 3146
        $string .= $line;
227 dpurdie 3147
    }
3148
    return $string;
3149
}
241 dpurdie 3150
#-------------------------------------------------------------------------------
3151
# Function        : PrintList
3152
#
3153
# Description     : Pretty format an array to fit within 80 char line
3154
#                   Perform wrapping as required
3155
#
3156
# Inputs          : $list           - Reference to an array
3157
#                   $nl             - New line stuff.
3158
#                                     Use to prefix new lines
3159
#
3160
# Returns         : string
3161
#
3162
sub PrintList
3163
{
6276 dpurdie 3164
    my ($platforms, $nl) = @_;
3165
    my ($string) = "";
3166
    my $maxLen = 100 - length($nl);
227 dpurdie 3167
 
6276 dpurdie 3168
    if ( @$platforms )
241 dpurdie 3169
    {
6276 dpurdie 3170
        my $line = "";
3171
        my $first = 1;
3172
        my $prefix = '';
3173
        foreach my $k ( sort @$platforms)
241 dpurdie 3174
        {
6276 dpurdie 3175
            if ((length($line) + length ($k) > $maxLen) && (!$first)) {
3176
                $string .= $line;
3177
                $line = $nl;
3178
                $prefix = '';
241 dpurdie 3179
            }
6276 dpurdie 3180
            $line .= $prefix . $k;
3181
            $first = 0;
3182
            $prefix = ' ';
241 dpurdie 3183
        }
6276 dpurdie 3184
        $string .= $line;
241 dpurdie 3185
    }
3186
    return $string;
3187
}
3188
 
305 dpurdie 3189
#-------------------------------------------------------------------------------
3190
# Function        : BuildReleaseFile
3191
#
3192
# Description     : Legacy function
3193
#                   Don't know what it was meant to do
3194
#                   Unfortunately it is present in a lot of build.pl files
3195
#
3196
#                   Not well supported on all machine types
3197
#
331 dpurdie 3198
# Inputs          : None that are used
305 dpurdie 3199
#
331 dpurdie 3200
# Returns         : Undefined
305 dpurdie 3201
#
227 dpurdie 3202
sub BuildReleaseFile
3203
{
6619 dpurdie 3204
    Warning("BuildReleaseFile directive does nothing and should be removed") unless $Clobber;
227 dpurdie 3205
}
3206
 
305 dpurdie 3207
#-------------------------------------------------------------------------------
3208
# Function        : BuildSnapshot
3209
#
3210
# Description     : Legacy function
3211
#                   Don't know what it was meant to do
3212
#                   Unfortunately it is present in a lot of build.pl files
3213
#
3214
# Inputs          : None that are used
3215
#
3216
# Returns         : Undefined
3217
#
227 dpurdie 3218
sub BuildSnapshot
3219
{
6619 dpurdie 3220
    Warning("BuildSnapshot directive does nothing and should be removed") unless $Clobber;
227 dpurdie 3221
}
3222
 
305 dpurdie 3223
#-------------------------------------------------------------------------------
3224
# Function        : BuildSrcArchive
3225
#
3226
# Description     : Create a source snapshot of the build source
3227
#                   Designed to provide a source image for packaging
3228
#                   examples
3229
#
3230
#                   Should be platform independent
3231
#
3232
#                   Creates an archive file and places it into the
3233
#                   interface directory. The archive will be packaged
3234
#                   automatically by the build process
3235
#
3236
#                   Use the 'pax' utility
3237
#                       1) Can massage the file path such that the stored
3238
#                          directory image contains the package name and version
3239
#
3240
#                   Directive can be used at any time before the BuildMake
3241
#
3242
#                   Will handle the existence of an auto.pl file by inserting
3243
#                   it as build.pl.
3244
#
6133 dpurdie 3245
# Inputs          : $platform   - In ABT mode. Process under this platform name
305 dpurdie 3246
#
3247
#
3248
# Returns         : 
3249
#
3250
sub BuildSrcArchive
3251
{
6133 dpurdie 3252
    my ($platform) = @_;
3253
    Error ("BuildSrcArchive requires one platform specifier") unless (defined $platform);
3254
 
3255
 
305 dpurdie 3256
    #
3257
    #   If we are clobbering, then there is nothing to do
3258
    #   The generated file is placed within the interface
3259
    #   directory and that directory will be deleted during the clobber
3260
    #
3261
    return if ( $Clobber );
3262
    DataDirective("BuildSrcArchive");
227 dpurdie 3263
 
305 dpurdie 3264
    #
6133 dpurdie 3265
    #   If not in ABT mode, then build archive on developers machine
3266
    #   In ABT mode only build the archive on a machine whose platform name is in the build filter
3267
    #
3268
    my $doBuild;
3269
    if (defined($::GBE_ABT))
3270
    {
3271
        if (defined ($::GBE_BUILDFILTER))
3272
        {
3273
            $doBuild  = grep( /^$platform/, split( ' ', $::GBE_BUILDFILTER ) );
3274
        }
3275
        unless ( $doBuild )
3276
        {
3277
            Log( "SrcPackage . Not on this machine" );
3278
            return; 
3279
        }
3280
    }
3281
 
3282
 
3283
    #
305 dpurdie 3284
    #   Currently this operation is only supported of some platforms
3285
    #   Only supported on Unix platforms
3286
    #   Uses the 'pax' utility
3287
    #
3288
    unless ( LocateProgInPath ( 'pax', '--All' ) && ( $ScmHost eq "Unix" ) )
3289
    {
3290
        Log( "SrcPackage . Not supported" );
3291
        return;
3292
    }
3293
 
3294
    #
3295
    #   Only allow one instance of the directive
3296
    #
3297
    Error ("Multiple BuildSrcArchive directives not supported")
3298
        if ( $build_source_pkg );
3299
 
3300
    #
3301
    #   Create the name of the archive
3302
    #       Based on the package name and version
3303
    #       Has no spaces
3304
    #
3305
    my $build_name = $BUILDNAME;
3306
    $build_name =~ s~\s+~_~g;
3307
 
3308
    #
3309
    #   Create the archive in the interface directory
3310
    #   Don't need to clobber it as the entire interface directory
3311
    #   will be clobbered
3312
    #
3313
    $build_source_pkg = $build_name;
3314
}
3315
 
3316
#-------------------------------------------------------------------------------
3317
# Function        : BuildSrcArchiveBody
227 dpurdie 3318
#
305 dpurdie 3319
# Description     : Function to implement the body of the BuildSrcArchive
3320
#                   operation. Will be invoked during BuildMake
3321
#
3322
# Inputs          : None
3323
#
3324
# Returns         : 
3325
#
3326
sub BuildSrcArchiveBody
3327
{
3328
    return unless ( $build_source_pkg );
3329
 
3330
    my $archive_dir = "pkg/$BUILDNAME_PACKAGE/src";
3331
    my $archive_file = "$build_source_pkg" . '.tar';
3332
 
3333
    Log( "SrcPackage . $archive_file.gz" );
3334
    unlink "$archive_dir/$archive_file";
3335
    unlink "$archive_dir/$archive_file.gz";
3336
    mkpath($archive_dir, 0, 0775);
3337
 
3338
    #
3339
    #   Create a list of files and top-level dirs to add to source archive
3340
    #   Many files are ignored
3341
    #   Should only be executed on the first 'build' thus many internal
3342
    #   directories will not be present
3343
    #
3344
    my @flist;
3345
    my $auto_pl;
3346
    opendir (my $tp, '.' ) or Error ("Cannot read current directory");
3347
    while ( $_ = readdir($tp) )
3348
    {
3349
        next if ( m/^\.$/ );
3350
        next if ( m'^\.\.$' );
3351
        next if ( m'^build\.log$' );
3352
        next if ( m'\.gbe$' );
6133 dpurdie 3353
        next if ( m'\.svn$' );
3354
        next if ( m'\.git$' );
3355
        next if ( m'\.cvs$' );
3356
        next if ( m'local_dpkg_archive$' );
3357
        next if ( m'\.jats.packageroot$' );
305 dpurdie 3358
        next if ( m'^local$' );
3359
        next if ( m'^pkg$' );
3360
        next if ( m/^$BUILDINTERFACE$/ );
3361
        $auto_pl = 1, next  if ( m'^auto\.pl$' );
3362
        next if (  m'^build\.pl$' );
3363
        next if ( m/^$build_source_pkg$/ );
3364
        push @flist, $_;
3365
    }
3366
    closedir $tp;
3367
 
3368
    #
3369
    #   If we don't have an auto.pl, then we add the build.pl file
3370
    #   If we do have a auto.pl - it gets tricky. Its don't after the
3371
    #   initial pax command
3372
    #
3373
    unless ( $auto_pl )
3374
    {
3375
        push @flist, 'build.pl';
3376
    }
3377
 
3378
    #
3379
    #   Create the command to be executed
3380
    #   Prefix archive paths with build_name
3381
    #
3382
    my @command = ( 'pax', '-w', '-f', "$archive_dir/$archive_file" );
3383
    System( '--NoShell' , @command, '-s', "~^~$build_source_pkg/~", @flist );
3384
 
3385
    #
3386
    #   If we have an auto.pl file, then we need to add it to the archive
3387
    #   but it needs to be called build.pl
3388
    #
3389
    if ( $auto_pl )
3390
    {
3391
        System( '--NoShell' , @command, '-a', '-s', "~^auto.pl~$build_source_pkg/build.pl~" , 'auto.pl' );
3392
    }
3393
 
3394
    #
3395
    #   Must now zip the file
3396
    #   Can't zip and append at the same time
3397
    #
3398
    System( '--NoShell' , 'gzip', "$archive_dir/$archive_file" );
3399
 
3400
    #
3401
    #   Display the results
3402
    #
3403
    System ('--NoShell', 'pax', '-z', "-f$archive_dir/$archive_file.gz")
3404
        if (IsVerbose (1));
3405
}
3406
 
3407
#-------------------------------------------------------------------------------
3408
# Function        : BuildAccessPerms
3409
#
3410
# Description     : Check if access/permissions setting requested...
3411
#                   Legacy
3412
#
331 dpurdie 3413
#                   Don't know what it was meant to do
3414
#                   Unfortunately it is present in a lot of build.pl files
305 dpurdie 3415
#
331 dpurdie 3416
# Inputs          : None that are used
305 dpurdie 3417
#
331 dpurdie 3418
# Returns         : Undefined
3419
#
227 dpurdie 3420
sub BuildAccessPerms
3421
{
6619 dpurdie 3422
    Warning("BuildAccessPerms directive does nothing and should be removed") unless $Clobber;
227 dpurdie 3423
}
3424
 
3425
 
3426
sub BuildSetenv
3427
{
6619 dpurdie 3428
    Warning("BuildSetenv directive does nothing and should be removed") unless $Clobber;
227 dpurdie 3429
    push( @BUILDSETENV, @_ );
3430
}
3431
 
3432
#-------------------------------------------------------------------------------
3433
# Function        : DataDirective
3434
#
3435
# Description     : Called by data collection directives to ensure that we are
3436
#                   still collecting data and that we have collected other data
3437
#
3438
# Inputs          : $dname              - Directive Name
3439
#
3440
# Returns         : Will error if we are not
3441
#
3442
sub DataDirective
3443
{
3444
    my ($dname) = @_;
3445
 
3446
    Error( "$dname() must appear after BuildName()...")
3447
        if ( $BUILDNAME eq "" );
3448
 
3449
    Error( "$dname() must appear after BuildInterface()...")
3450
        unless( $BUILDINTERFACE );
3451
 
3452
    Error( "$dname() not allowed after BuildDescpkg, BuildIncpkg, BuildVersion or BuildMake")
3453
        if( $BUILDPHASE);
3454
}
3455
 
3456
#-------------------------------------------------------------------------------
3457
# Function        : StartBuildPhase
3458
#
3459
# Description     : Called by directives that deal with the building phases
3460
#                   to perform common initialisation and to ensure that
3461
#                   directives that collect data are no longer called
3462
#
305 dpurdie 3463
# Inputs          : last                - True: Last directive expected
227 dpurdie 3464
#
3465
# Returns         : May generate an error
3466
#
3467
sub StartBuildPhase
3468
{
305 dpurdie 3469
    my ($last) = @_;
3470
 
227 dpurdie 3471
    #
305 dpurdie 3472
    #   Ensure directive is allowed
3473
    #       $BUILDPHASE >  1     - No more directives allowed
3474
    #       $BUILDPHASE == 1     - Allowed directive
3475
    #
3476
    if ( $BUILDPHASE > 1 )
3477
    {
3478
        my $function = (caller(1))[3];
3479
        $function =~ s~.*::~~;
3480
        Error ("Directive not allowed: $function","'BuildMake' must be the last directive in the build file");
3481
    }
3482
 
3483
    #
227 dpurdie 3484
    #   Only do it once
3485
    #
305 dpurdie 3486
    return if ( $BUILDPHASE  );
3487
    $BUILDPHASE = 1;
227 dpurdie 3488
 
3489
    #
341 dpurdie 3490
    #   If we are not performing a ForceBuild, then we don't need to continue
3491
    #   We have updated the interface directory with BuildPkgArchive
3492
    #   information.
3493
    #
3494
    TestForForcedBuild();
3495
 
3496
    #
6133 dpurdie 3497
    #   Calculate the aliases that are being extracted from targets
227 dpurdie 3498
    #
3499
    Process_TargetAlias();
3500
 
3501
    #
6198 dpurdie 3502
    #   Calculate defined aliases
6133 dpurdie 3503
    #       Limit the Aliases to active platforms
6198 dpurdie 3504
    #       ie: NATIVE INSTRUMENT PKG_WIN PKG_RPM PKG_DEB SK
4728 dpurdie 3505
    #
6276 dpurdie 3506
    my %activePlatformMap;
3507
    foreach my $item ( keys %BUILDINFO) {
3508
           my $pInfo = $BUILDINFO{$item};
3509
           next if $pInfo->{NOT_AVAILABLE} > 1; 
3510
           push @{$activePlatformMap{$pInfo->{TARGET}}}, $item;
3511
    }
3512
 
6198 dpurdie 3513
    foreach my $alias ( @PlatformConfig::BuildAliases )
4728 dpurdie 3514
    {
6276 dpurdie 3515
        if (exists $BUILDALIAS{$alias})  
4728 dpurdie 3516
        {
6198 dpurdie 3517
            # Will occur if GBE_ABT has been set, for backward compatibility
6133 dpurdie 3518
            Warning("User has manually specified a $alias alias",'Default alias will not be set.');
6276 dpurdie 3519
            #DebugDumpData("BUILDALIAS", \%BUILDALIAS);
4728 dpurdie 3520
        }
6133 dpurdie 3521
        else
3522
        {
6276 dpurdie 3523
            my @activeAliases;
3524
            foreach my $item (PlatformConfig::getTargetsByTag($alias)) {
3525
                if (exists($activePlatformMap{$item})) {
3526
                    push (@activeAliases, @{$activePlatformMap{$item}});
6177 dpurdie 3527
                }
3528
            }
6276 dpurdie 3529
 
6133 dpurdie 3530
            $BUILDALIAS{$alias} = join(' ', @activeAliases) if (@activeAliases);
3531
 
3532
            #
3533
            #   Add to the build entry too
3534
            #
6276 dpurdie 3535
            foreach my $aliasTarget (@activeAliases) {
6133 dpurdie 3536
                push @{$BUILDINFO{$aliasTarget}{USERALIAS}}, $alias;
3537
            }
3538
        }
4728 dpurdie 3539
    }
6133 dpurdie 3540
    CleanUp_Aliases();
6276 dpurdie 3541
    ProcessBuildArgument();
6684 dpurdie 3542
    ProcessLinkPkgExclude();
4728 dpurdie 3543
 
3544
    #
311 dpurdie 3545
    #   Create dummy package to describe the Interface directory
3546
    #
3547
    CreateInterfacePackage();
3548
 
3549
    #
227 dpurdie 3550
    #   Sanity test the users packages
6133 dpurdie 3551
    #       In a sandbox all bet are off
227 dpurdie 3552
    #
6133 dpurdie 3553
    PackageEntry::SanityTest() unless ($Clobber || $::GBE_SANDBOX);
227 dpurdie 3554
 
3555
    #
3556
    #   Validate the $Srcdir before its first real use
3557
    #   This is calculated from the user directives
3558
    #
3559
 
3560
    #.. Determine default "source" root
3561
    #
3562
    if ( $Srcdir eq "" )
3563
    {
3564
        Warning( "Both the directories 'src' and 'SRC' exist ....." )
3565
            if ( $ScmHost eq "Unix" && -e "src" && -e "SRC" );
3566
 
3567
        if ( -e "src" ) {
3568
            $Srcdir = "src";
3569
        } else {
3570
            ( -e "SRC" ) ||
3571
                Error( "Neither the directory 'src' nor 'SRC' exist ....." );
3572
            $Srcdir = "SRC";
3573
        }
3574
    }
3575
 
3576
    #
3577
    #   Must have a valid Srcdir
3578
    #
3579
    Error ("Source directory not found: $Srcdir")
3580
        unless ( $Srcdir && -d $Srcdir );
3581
 
305 dpurdie 3582
    #
3583
    #   Create source package
3584
    #
3585
    BuildSrcArchiveBody();
3586
 
227 dpurdie 3587
    return $Srcdir;
3588
}
3589
 
3590
#-------------------------------------------------------------------------------
341 dpurdie 3591
# Function        : TestForForcedBuild
3592
#
3593
# Description     : If a non-forced build has been requested, then see
3594
#                   if a build is required ( ie: build.pl modified )
6133 dpurdie 3595
#                   
3596
#                   Check:
3597
#                       Time stamp of build.pl
3598
#                       Time stamp of Makefile.gbe
3599
#                       BuildFilter has not changed
3600
#                       Signature of dependencies has not changed
3601
#                       No packages consumed from within the sandbox
341 dpurdie 3602
#
3603
# Inputs          : None
3604
#
3605
# Returns         : May not return
6133 dpurdie 3606
#                   Will return if we need to perform a build
341 dpurdie 3607
#
3608
sub TestForForcedBuild
3609
{
3610
    #
3611
    #   Always return if in clobber mode
3612
    #
3613
    return if ( $Clobber );
3614
 
3615
    if ( ! $ForceBuild  )
3616
    {
3617
        my @build_warn;
6276 dpurdie 3618
        my $bstamp = -M "$CwdFull/$ScmBuildSrc";
3619
        my $tstamp = -M "$CwdFull/Makefile.gbe";
341 dpurdie 3620
 
3621
        push @build_warn, "Missing: Makefile.gbe" unless ( defined $tstamp );
3622
        push @build_warn, "Modified build file ($ScmBuildSrc)" if ( $tstamp && $bstamp < $tstamp );
3623
 
363 dpurdie 3624
        #
3625
        #   Ensure that the build filter has not changed
3626
        #   If the user has changed the buildfilter, then we need to
3627
        #   force a build.
3628
        #
6133 dpurdie 3629
        #   The root Makefile.gbe will have a $ScmBuildFilter entry
363 dpurdie 3630
        #
3631
        unless ( @build_warn )
3632
        {
3633
            use JatsMakeInfo;
3634
            ReadMakeInfo();
5726 dpurdie 3635
            my $line = $::ScmBuildFilter || '';
3636
            $line =~ s~\s+~ ~g;
363 dpurdie 3637
 
5726 dpurdie 3638
            my $filter = $::GBE_BUILDFILTER || '';
3639
            $filter =~ s~\s+~ ~g;
3640
            if ( $line ne $filter )
3641
            {
3642
                push @build_warn, "Build filter has changed";
3643
                Verbose2 ("Buildfilter Test: Was:$line, Is:$::GBE_BUILDFILTER");
3644
            }
363 dpurdie 3645
        }
3646
 
6133 dpurdie 3647
        #
3648
        #   If any of the imported packages are from a sandbox, then we must force a build
3649
        #   and a make.
3650
        #
3651
        if ($pkgFromSandbox)
3652
        {
3653
            push @build_warn, "Consuming packages from within the sandbox";
3654
        }
3655
 
341 dpurdie 3656
        if ( @build_warn )
3657
        {
363 dpurdie 3658
            Verbose ("Forcing Build.", @build_warn );
341 dpurdie 3659
        }
3660
        else
3661
        {
3662
            Verbose ("No build performed. Build files up to date");
3663
            Log ("Build files up to date") if $::GBE_SANDBOX;
3664
            exit 0;
3665
        }
3666
    }
3667
}
3668
 
3669
#-------------------------------------------------------------------------------
305 dpurdie 3670
# Function        : LastBuildDirective
3671
#
3672
# Description     : No more build directives allowed
3673
#
3674
# Inputs          : 
3675
#
3676
# Returns         : 
3677
#
3678
sub LastBuildDirective
3679
{
3680
    $BUILDPHASE = 2;
3681
}
3682
 
3683
#-------------------------------------------------------------------------------
227 dpurdie 3684
# Function        : BuildPackageLink
3685
#
3686
# Description     : Create a soft link from sandbox_dpkg_archive to the package
3687
#                   being created by this build
3688
#
3689
#                   For backward compatability.
3690
#                   If GBE_DPKG_SBOX is not defined, then use GBE_DPKG_LOCAL
3691
#
3692
#                   This will allow multiple components to work together
3693
#
3694
#                   Note: When called in Clobber-mode the link will be deleted
3695
#
3696
# Inputs          : $BUILDNAME              - The package name
3697
#                   $BUILDNAME_PROJECT      - Project extension
3698
#                   $::GBE_DPKG_SBOX        - Path of sandbox_dpkg_archive
3699
#                   $::GBE_DPKG_LOCAL       - Path of local_dpkg_archive
3700
#                   $::GBE_DPKG             - Main repository
3701
#
3702
# Returns         : Nothing
3703
#
3704
sub BuildPackageLink
3705
{
3706
    my $target_archive;
3707
    my $target_archive_name;
3708
    my $link_file;
3709
    my $tag;
371 dpurdie 3710
    my $root_path;
227 dpurdie 3711
 
3712
    #
6276 dpurdie 3713
    #   In the build system we do NOT want to consume packages from within the sandbox
3714
    #   because they may be partially formed. They need to be consumed from a published
3715
    #   archive.
3716
    #   
3717
    #   If we are in an ABT sandbox, then don't create a link file
3718
    #   
3719
    return if (defined($::GBE_ABT));
3720
 
3721
    #
227 dpurdie 3722
    #   Determine the path (and name) of the target archive
3723
    #   Use sandbox_dpkg_archive if it exists
3724
    #   Use local_dpkg_acrhive for backward compatability (should be removed after JATS 2.64.2+)
3725
    #
3726
    if ( $target_archive = $::GBE_DPKG_SBOX )
3727
    {
3728
        $target_archive_name = "sandbox_dpkg_archive";
3729
        $tag = "Sandbox";
359 dpurdie 3730
        if ( $sandbox_exact )
3731
        {
3732
            $link_file = "$BUILDVERSION.lnk";
3733
        }
3734
        else
3735
        {
3736
            $link_file  = 'sandbox' . ${BUILDNAME_SUFFIX} . '.lnk';
3737
        }
6276 dpurdie 3738
        $root_path = 'GBE_SANDBOX' . substr($CwdFull, length($::GBE_SANDBOX));
371 dpurdie 3739
        Verbose2("Root Path: $::GBE_SANDBOX, $root_path");
227 dpurdie 3740
    }
3741
    elsif ( $target_archive = $::GBE_DPKG_LOCAL )
3742
    {
3743
        $target_archive_name = "local_dpkg_archive";
3744
        $link_file = "$BUILDVERSION.lnk";
3745
        $tag = "Local";
6276 dpurdie 3746
        $root_path = $CwdFull;
227 dpurdie 3747
    }
3748
    else
3749
    {
3750
        Verbose("Cannot locate local or sandbox archive")
3751
            unless $Clobber;
3752
        return;
3753
    }
3754
 
3755
    #
3756
    #   Santity test
3757
    #   Target must be a directory
3758
    #
3759
    unless ( -d $target_archive )
3760
    {
241 dpurdie 3761
        Warning("$target_archive_name is not a directory: $target_archive")
227 dpurdie 3762
            unless $Clobber;
3763
        return;
3764
    }
3765
 
3766
    my $link_dir = "$target_archive/$BUILDNAME_PACKAGE";
3767
    my $link_path = "$link_dir/$link_file";
3768
 
6133 dpurdie 3769
    if ( $Clobber || $NoBuild )
227 dpurdie 3770
    {
3771
        unlink $link_path;          # Delete the link
3772
        rmdir $link_dir;            # Delete only if empty
3773
    }
3774
    else
3775
    {
261 dpurdie 3776
        Log( "Local Link . $BUILDNAME_PACKAGE/$link_file ($tag)");
3777
        mkdir $link_dir unless -d $link_dir;
371 dpurdie 3778
        FileCreate ( $link_path, "$root_path/pkg/$BUILDNAME_PACKAGE");
227 dpurdie 3779
    }
3780
}
3781
 
3782
#-------------------------------------------------------------------------------
3783
# Function        : BuildSandboxData
3784
#
3785
# Description     : Create data structures to allow this package to be built
3786
#                   within a multi-package sandbox.
3787
#
3788
#                   This will allow multiple components to work together
6133 dpurdie 3789
#                   Creates:
3790
#                       sandbox.int     - Rel path to the packages interface
3791
#                       sandbox.ffp     - Fast FingerPrint over the package body
3792
#                       sandbox.nob     - No Build marker
227 dpurdie 3793
#
3794
#                   Note: When called in Clobber-mode the link will be deleted
3795
#
3796
# Inputs          : $BUILDNAME              - The package name
3797
#                   $BUILDNAME_PROJECT      - Project extension
3798
#                   $::GBE_DPKG_SBOX        - Path of sandbox_dpkg_archive
3799
#                   $::GBE_DPKG             - Main repository
3800
#
3801
# Returns         : Nothing
3802
#
3803
sub BuildSandboxData
3804
{
3805
    my $sandbox_dpkg_archive = $::GBE_DPKG_SBOX;
3806
    return unless ( $sandbox_dpkg_archive );
3807
 
3808
    unless ( -d $sandbox_dpkg_archive )
3809
    {
241 dpurdie 3810
        Error("sandbox_dpkg_archive is not a directory: $sandbox_dpkg_archive")
227 dpurdie 3811
            unless $Clobber;
3812
        return;
3813
    }
3814
 
3815
    #
3816
    #   Create a name for this package in the sandbox
7441 dpurdie 3817
    #       Must use the package name and extension - unless exact sandbox
3818
    #       Must use packahe name, version and extension if its an exact sandbox
227 dpurdie 3819
    #
3820
    my $link_dir = "$sandbox_dpkg_archive/$BUILDNAME_PACKAGE";
6133 dpurdie 3821
    my $base = 'sandbox' . ${BUILDNAME_SUFFIX}; 
7441 dpurdie 3822
    if ($sandbox_exact) {
3823
        $base = 'sandbox.' . ${BUILDNAME_VERSION} . ${BUILDNAME_SUFFIX}; 
3824
    }
359 dpurdie 3825
 
6133 dpurdie 3826
    my $nob_path  = $base . ".nob";
3827
    my $ffp_path  = $base . ".ffp";
3828
    my $int_path  = $base . ".int";
227 dpurdie 3829
 
6133 dpurdie 3830
    $nob_path = "$link_dir/$nob_path";
3831
    $ffp_path = "$link_dir/$ffp_path";
3832
    $int_path = "$link_dir/$int_path";
3833
 
227 dpurdie 3834
    if ( $Clobber )
3835
    {
3836
        rmdir $link_dir;            # Delete only if empty
3837
    }
3838
    else
3839
    {
6133 dpurdie 3840
        ToolsetFiles::AddFile($nob_path);
3841
        ToolsetFiles::AddFile($ffp_path);
3842
        ToolsetFiles::AddFile($int_path);
3843
 
3844
        #Log( "Sandbox Data. $base");
3845
        unlink $int_path;
227 dpurdie 3846
        mkdir $link_dir;
3847
 
3848
        #
6133 dpurdie 3849
        #   File with path to the interface directory
3850
        #   Relative to the base of the sandbox
227 dpurdie 3851
        #
6276 dpurdie 3852
        FileCreate($int_path, CatPaths('GBE_SANDBOX',RelPath($CwdFull,$::GBE_SANDBOX),$BUILDINTERFACE ));
227 dpurdie 3853
 
3854
        #
6133 dpurdie 3855
        #   Indicate packages not build on this machine
227 dpurdie 3856
        #
6133 dpurdie 3857
        unlink $nob_path;           # Delete the NoBuild marker
3858
        if ($NoBuild) {
3859
            TouchFile($nob_path);
3860
        }
227 dpurdie 3861
    }
3862
}
3863
 
3864
 
3865
#-------------------------------------------------------------------------------
3866
# Function        : BuildMake
3867
#
3868
# Description     : Generate the makefiles
3869
#                   This directive MUST be the last directive in the build.pl
3870
#                   file. The directive triggers the processing of all the
3871
#                   information that has been collected
3872
#
3873
#
3874
# Inputs          : None
3875
#
3876
# Returns         : Nothing
3877
#
3878
 
3879
sub BuildMake
3880
{
3881
    my( $argc, $platform );
3882
 
3883
    #
3884
    #   Must have a valid $BUILDINTERFACE
3885
    #   Normally this is held in the interface directory, but this is not
3886
    #   always created. If there is no $BUILDINTERFACE, then use the
3887
    #   build directory
3888
    #
6133 dpurdie 3889
    BuildInterfaceInternal($::ScmInterface) unless ( $BUILDINTERFACE );
227 dpurdie 3890
 
6133 dpurdie 3891
 
227 dpurdie 3892
    #.. Starting the build phase. No more data collection
3893
    #
305 dpurdie 3894
    StartBuildPhase();
3895
    LastBuildDirective();
227 dpurdie 3896
 
5109 dpurdie 3897
    #
3898
    #   Now that the bulk of the information has been displayed
3899
    #   we can display captured messages. These warnings will be 
3900
    #   at the end of the log so that users can see them.
3901
    DumpCapture();
3902
 
227 dpurdie 3903
    sub DeleteCfg
3904
    {
3905
        #
3906
        #   Delete files that will be re-created
3907
        #   Some of these files are read and written.
3908
        #   Errors in the files are solved by deleting the files now.
3909
        #
3910
        unlink "$BUILDINTERFACE/build.cfg";
3911
        unlink "$BUILDINTERFACE/Makefile.cfg";
3912
        unlink glob ("$BUILDINTERFACE/Makefile*.cfg");
3913
        unlink "$BUILDINTERFACE/Buildfile.cfg";
3914
        unlink "$BUILDINTERFACE/Dpackage.cfg";
3915
    }
3916
 
3917
    if ( $Clobber )                             # clobber mode ?
3918
    {
4003 dpurdie 3919
        #
3920
        #   Delete my own configuration files
3921
        #
227 dpurdie 3922
        DeleteCfg();
3923
 
3924
        #
3925
        #   JATS creates a 'pkg' directory for the target package
3926
        #
3927
        push @CLOBBERDIRS, "pkg";
3928
 
3929
        #
3930
        #   Deployment creates a 'build/deploy' directory
375 dpurdie 3931
        #   The 'build' directory may contain user files - only remove if empty
227 dpurdie 3932
        #
3933
        push @CLOBBERDIRS, "build/deploy";
375 dpurdie 3934
        push @REMOVEDIRS, "build";
227 dpurdie 3935
 
3936
        #
6133 dpurdie 3937
        #   List of files maintained by the build system
3938
        #
3939
        my @toolsetFiles = ToolsetFiles::GetFiles();
3940
 
3941
        #
227 dpurdie 3942
        #   Delete interface directories and other directories that have been
375 dpurdie 3943
        #   marked to be clobbered
227 dpurdie 3944
        #
3945
        foreach my $dir ( @CLOBBERDIRS )
3946
        {
3947
            next if ( $dir eq '.' );
3948
            next if ( $dir eq '..' );
3949
            if ( -d $dir )
3950
            {
361 dpurdie 3951
                RmDirTree ( $dir );
227 dpurdie 3952
            }
3953
        }
3954
 
375 dpurdie 3955
        foreach my $dir ( @REMOVEDIRS )
3956
        {
3957
            next if ( $dir eq '.' );
3958
            next if ( $dir eq '..' );
3959
            if ( -d $dir )
3960
            {
3961
                rmdir ( $dir ); # Only if empty
3962
            }
3963
        }
3964
 
6133 dpurdie 3965
        foreach my $file (@toolsetFiles)
227 dpurdie 3966
        {
6133 dpurdie 3967
            RmDirTree ( $file ) if ( -f $file );
227 dpurdie 3968
        }
3969
 
3970
        #
3971
        #   DPACKAGE may be a user file, Only delete it if we created it
3972
        #
299 dpurdie 3973
        unlink "$Srcdir/DPACKAGE.$::GBE_MACHTYPE" if $DeleteDPACKAGE;
227 dpurdie 3974
 
3975
        BuildPackageLink();
3976
        BuildSandboxData();
3977
        return;
3978
    }
6276 dpurdie 3979
    #
3980
    #   Generate the path to the descpkg file
3981
    #   The file is created later in the build proccess, but the makefile generation 
3982
    #   needs to have a known path to the file.
3983
    #    
3984
    #   It will be a file that is 'known' to JATS
3985
    #
3986
    $descpkgPath = BuildAddKnownFile ( $NoBuild ? $CwdFull : $Srcdir, 'descpkg' );
227 dpurdie 3987
 
3988
    #.. Build support files
3989
    #
3990
    DeleteCfg();
3991
    BuildConfig();
3992
    BuildSharedLibFiles();
3993
    WriteParsedBuildConfig();
3994
    BuildPackageLink();
3995
    BuildSandboxData();
3996
 
3997
    #
3998
    #  ONLY (re)building interface dir
3999
    #
6276 dpurdie 4000
    unless ( $Interface ) {
227 dpurdie 4001
 
6276 dpurdie 4002
        #---------------------------------------------------------------------------
4003
        #
4004
        #.. Make bootstrap "makefile",
4005
        #   Simulate a top level makefile
4006
        #       Pass argumenst to makelib
4007
        #       Sumulate SubDir() operations
4008
        #       Sumulate a Platform(*);
4009
        #
4010
        #       Due to the normal way that makelib.pl is executed,
4011
        #       the following substitutions are done.
4012
        #
4013
        @ARGV = ();
4014
        $0 = "makefile.pl ";
4015
        push @ARGV, "$CwdFull";                         # current working directory
4016
        push @ARGV, "$::GBE_TOOLS/makelib.pl";      # makelib.pl image
4017
        push @ARGV, "--interface=$BUILDINTERFACE"
4018
            if ($BUILDINTERFACE);
227 dpurdie 4019
 
6276 dpurdie 4020
        Debug( "ARGV:      @ARGV" );
227 dpurdie 4021
 
6276 dpurdie 4022
        #.. (re)Build root makefile
4023
        #
4024
        $ScmBuildlib = 0;                           # clear Buildlib flag for 'makelib.pl'
4025
        RootMakefile();                             # inform 'makelib.pl'
4026
        MakeLibInit();                              # run initialisation
227 dpurdie 4027
 
6276 dpurdie 4028
        #.. Register subdir(s)
4029
        #
4030
        UniquePush (\@BUILDSUBDIRS, $Srcdir );
4031
        SubDir( @BUILDSUBDIRS );
4032
        Platform( @BUILD_ACTIVEPLATFORMS );
227 dpurdie 4033
 
6276 dpurdie 4034
        #.. (re)build src makefiles and associated information
4035
        #   JatsTool will not return on error
4036
        #
4037
        my @cmds = ('jmake.pl', 'rebuild');
4038
        push @cmds, 'NORECURSE=1' if ( $RootOnly );
4039
        JatsTool ( @cmds);
4040
    }
4041
 
227 dpurdie 4042
    #
6276 dpurdie 4043
    #   Generate package signature
4044
    #   Write the descpkg file again - with a signature this time
4045
    #
4046
    ErrorConfig( 'name' => 'buildlib')   ;
4047
    WriteDescpkg();
4048
    NoBuildMarker();
305 dpurdie 4049
 
4050
    #
4051
    #   Generate some warnings that will be seen at the end of the build
4052
    #
4053
    Warning ("BuildSrcArchive Directive Present","Read JATS Manual for correct usage")
4054
        if ($build_source_pkg);
227 dpurdie 4055
}
4056
 
4057
 
4058
#-------------------------------------------------------------------------------
4059
# Function        : BuildVersion
4060
#
4061
# Description     : Generate version.c and version.h files
4062
#
4063
# Inputs          : Options
4064
#                       --Prefix=prefix         Text prepended to variables created
4065
#                                               as a part of the "C" versions
4066
#                       --Type=type             Type of "C" style data
4067
#                                               Allowed types are: array
4068
#                       --Defs=name             Generate a "C" definitions file.
4069
#                                               This file simply contains definitions
4070
#                       --Defs                  Same as --Defs=defs
4071
#                       --Style=style           Output file style
4072
#                                               Supported styles:
4073
#                                                   "C" - Default
4074
#                                                   "CSharp"
4075
#                                                   "WinRC"
289 dpurdie 4076
#                                                   "Delphi"
315 dpurdie 4077
#                                                   "VB"
227 dpurdie 4078
#                       --File=name             Specifies the output file name
4079
#                                               Default is determined by the style
4080
#
4081
#                   Also allows for an 'old' style format in which
4082
#                   the first three arguments are prefix,type and defs
4083
# Returns         :
4084
#
4085
 
4086
sub BuildVersion
4087
{
4088
    my ( $Prefix, $Type, $Mode ) = @_;
4089
    my $ModePrefix;
4090
    my $Style = "C";
4091
    my $FileName;
4092
    my $VersionFiles;
267 dpurdie 4093
    my @opts;
4094
    my $supports_opts;
227 dpurdie 4095
 
4096
    StartBuildPhase();                          # Starting the build phase. No more data collection
4097
 
279 dpurdie 4098
    if ( defined($Prefix) && $Prefix =~ /^-/ )
227 dpurdie 4099
    {
4100
        $Prefix = undef;
4101
        $Type = undef;
4102
        $Mode = undef;
4103
        foreach  ( @_ )
4104
        {
4105
            if (      /^--Prefix=(.*)/ ) {
4106
                $Prefix = $1;
4107
                $VersionFiles = 1;
4108
 
4109
            } elsif ( /^--Type=(.*)/ ) {
4110
                $Type = $1;
4111
                $VersionFiles = 1;
4112
 
4113
            } elsif ( /^--Defs=(.*)/ ) {
4114
                $Mode = $1;
4115
                $ModePrefix = "_$1";
4116
 
4117
            } elsif ( /^--Defs$/ ) {
4118
                $Mode = 'defs';
4119
                $ModePrefix = "";
4120
 
4121
            } elsif ( /^--Style=(.*)/ ) {
4122
                $Style = $1;
279 dpurdie 4123
                $VersionFiles = 1;
267 dpurdie 4124
                $supports_opts = 1 if ( $Style =~ /^WinRC/i );
227 dpurdie 4125
 
4126
            } elsif ( /^--File=(.*)/ ) {
4127
                $FileName = $1;
4128
 
267 dpurdie 4129
            } elsif ($supports_opts ) {
4130
                push @opts, $_;
235 dpurdie 4131
 
227 dpurdie 4132
            } else {
4133
                Error ("BuildVersion: Unknown option: $_");
4134
 
4135
            }
4136
        }
4137
    }
4138
    else
4139
    {
4140
        #
4141
        #   Old style positional arguments.
4142
        #
4143
        $VersionFiles = 1;
4144
        if ( defined( $Mode ) )
4145
        {
4146
            if ( $Mode =~ m/^defs(=(.*))?$/i )
4147
            {
4148
                $Mode       = $2 ? $2    : 'defs';
4149
                $ModePrefix = $2 ? "_$2" : "";
4150
            }
4151
            else
4152
            {
4153
                Error ("BuildVersion: Bad Mode argument. Need 'defs' or 'defs=name'");
4154
            }
4155
        }
4156
    }
4157
 
4158
    #
4159
    #   Determine the style of version file to create
4160
    #
4161
    if ( $Style =~ /^CSharp/i ) {
4162
        BuildVersionCSharp( $FileName );
4163
 
229 dpurdie 4164
    } elsif ( $Style =~ /^Properties/i ) {
4165
        BuildVersionProperties( $FileName, $Prefix );
4166
 
227 dpurdie 4167
    } elsif ( $Style =~ /^WinRC/i ) {
267 dpurdie 4168
        BuildVersionWinRC( $FileName, @opts );
227 dpurdie 4169
 
289 dpurdie 4170
    } elsif ( $Style =~ /^Delphi/i ) {
4171
        BuildVersionDelphi( $FileName, $Prefix );
315 dpurdie 4172
 
4173
    } elsif ( $Style =~ /^VB/i ) {
4174
        BuildVersionVB( $FileName, $Prefix );
289 dpurdie 4175
 
227 dpurdie 4176
    } elsif ( $Style eq "C" ) {
289 dpurdie 4177
        BuildVersionC    ( $FileName, $Prefix, $Type )     if ( $VersionFiles );
4178
        BuildVersionCdefs( $FileName, $Mode, $ModePrefix ) if ( $Mode );
227 dpurdie 4179
 
4180
    } else {
4181
        Error("BuildVersion: Unknown style: $Style");
4182
    }
4183
}
4184
 
4185
#-------------------------------------------------------------------------------
4186
# Function        : BuildDescpkg
4187
#
4188
# Description     : Create a package description file
4189
#                   The format of this file matches that generated by JANTS
4190
#                   Take care when extending the format
4191
#
4192
#                   NOTE: It turns out that JANTS is not a standard and the
4193
#                         implementors (of JANTS) kept on changing it.
6276 dpurdie 4194
#                         
4195
#                   NOTE: This directive is now ignored
4196
#                         The descpkg file is generated internally
227 dpurdie 4197
#
6276 dpurdie 4198
# Inputs          : $mode - 'Internal' - Skip sanity test
227 dpurdie 4199
#
4200
# Returns         :
4201
#
4202
sub BuildDescpkg
4203
{
6276 dpurdie 4204
    StartBuildPhase();                  # Starting the build phase. No more data collection
4205
}
4206
 
4207
#-------------------------------------------------------------------------------
4208
# Function        : WriteDescpkg 
4209
#
4210
# Description     : Create a package description file
4211
#                   The format of this file matches that generated by JANTS
4212
#                   Take care when extending the format
4213
#
4214
#                   NOTE: It turns out that JANTS is not a standard and the
4215
#                         implementors (of JANTS) kept on changing it.
4216
#
4217
# Inputs          :  
4218
#
4219
# Returns         : 
4220
#
4221
sub WriteDescpkg
4222
{
4003 dpurdie 4223
    return if ( $Clobber );                 # clobber mode ?
227 dpurdie 4224
 
261 dpurdie 4225
    my @desc;
279 dpurdie 4226
    push @desc, "Package Name:  $BUILDNAME_PACKAGE";
4227
    push @desc, "Version:       $BUILDVERSION";
4228
    push @desc, "Released By:   $::USER";
4229
    push @desc, "Released On:   $::CurrentTime";
4230
    push @desc, "Build Machine: $::GBE_HOSTNAME";
6276 dpurdie 4231
    push @desc, "Path:          $CwdFull";
279 dpurdie 4232
    push @desc, "Jats Version:  $::GBE_VERSION";
4233
    push @desc, "Jats Path:     $::GBE_CORE";
261 dpurdie 4234
    push @desc, "";
4235
    push @desc, "Build Dependencies:";
4236
    push @desc, "";
227 dpurdie 4237
 
4238
    foreach my $tag ( PackageEntry::GetPackageList )
4239
    {
4240
        my ($name, $version, $type) = PackageEntry::GetPackageData($tag);
4241
 
4242
        my @attributes;
4243
 
4244
        push @attributes, "name=\"$name\"";
4245
        push @attributes, "version=\"$version\"";
4246
        push @attributes, "build=\"true\"" if $type =~ /Build/i;
4247
 
261 dpurdie 4248
        push @desc, "<sandbox @attributes/>";
227 dpurdie 4249
    }
247 dpurdie 4250
 
6276 dpurdie 4251
    FileCreate ($descpkgPath, \@desc );
227 dpurdie 4252
}
4253
 
4254
#-------------------------------------------------------------------------------
4003 dpurdie 4255
# Function        : NoBuildMarker
4256
#
4257
# Description     : Maintain the nobuild marker
4258
#                   This is file placed in the interface directory simply
4259
#                   to indicate to the 'create_dpkg' utility that this build
4260
#                   does not do anything useful.
4261
#
6133 dpurdie 4262
#                   It will only be used on a build machine by the build daemon
4003 dpurdie 4263
#
4264
#                   Its not placed in the interface directory as it would be
4265
#                   harder for create_dpkg to find it.
4266
#
4267
# Inputs          : None
4268
# Globals         : $NoBuild, $Clobber
4269
#
4270
# Returns         : Nothing
4271
#
4272
sub NoBuildMarker
4273
{
4274
    return if ( $Clobber );
4275
 
4276
    # Always delete the file - in case we toggle build forms
4277
    #
5986 dpurdie 4278
    my $markerFile = BuildAddKnownFile( $::ScmRoot, 'noBuild.gbe');
4003 dpurdie 4279
    unlink($markerFile);
4280
 
4281
    TouchFile($markerFile)
4282
        if ($NoBuild);
4283
}
4284
 
4285
#-------------------------------------------------------------------------------
227 dpurdie 4286
# Function        : BuildIncpkg
4287
#
4288
# Description     : Create a package inclusion file
4289
#
4290
# Inputs          :
4291
#
4292
# Returns         :
4293
#
4294
sub BuildIncpkg
4295
{
4296
    StartBuildPhase();                          # Starting the build phase. No more data collection
4297
    if ( $Clobber )                             # clobber mode ?
4298
    {
361 dpurdie 4299
        RmDirTree( "$Srcdir/incpkg" );
227 dpurdie 4300
        return;
4301
    }
4302
 
4303
    my $fh = ConfigurationFile::New( "$Srcdir/incpkg" );
4304
    $fh->Header( "buildlib (Version $BuildVersion)",
4305
                              "Package inclusion list" );
4306
 
4307
    foreach my $tag ( PackageEntry::GetPackageList )
4308
    {
4309
        my ($name, $version, $type) = PackageEntry::GetPackageData($tag);
4310
        $type = ($type =~ /build/i) ? "Build" : "Link";
4311
 
4312
        $fh->Write( "${type}PkgArchive( '$name', '$version' );\n" );
4313
    }
4314
 
4315
    $fh->Close();
4316
}
4317
 
4318
#-------------------------------------------------------------------------------
4319
# Function        : BuildConfig
4320
#
4321
# Description     : Create the file interface/build.cfg
4322
#                   This file contains information gathered by the build process
4323
#                   that is to be used when makefiles are created and re-created
4324
#
4325
# Inputs          : None
4326
#
4327
# Returns         : Nothing
4328
#
283 dpurdie 4329
sub BuildConfig
227 dpurdie 4330
{
4331
    Error( "No BuildInterface directive encountered\n" )
4332
        unless ($BUILDINTERFACE);
4333
 
4334
    my $fh = ConfigurationFile::New( "$BUILDINTERFACE/build.cfg");
4335
    $fh->Header( "buildlib (Version $BuildVersion)",
4336
                              "Makelib configuration file", "
4337
\$ScmBuildMachType              = \"$::GBE_MACHTYPE\";
4338
\$ScmInterfaceVersion           = \"$::InterfaceVersion\";
4339
\$ScmBuildName                  = \"$BUILDNAME\";
4340
\$ScmBuildPackage               = \"$BUILDNAME_PACKAGE\";
4341
\$ScmBuildVersion               = \"$BUILDNAME_VERSION\";
4342
\$ScmBuildProject               = \"$BUILDNAME_PROJECT\";
4343
\$ScmBuildVersionFull           = \"$BUILDVERSION\";
6511 dpurdie 4344
\$ScmBuildBaseVersion           = \"$BUILDBASEVERSION\";
227 dpurdie 4345
\$ScmBuildPreviousVersion       = \"$BUILDPREVIOUSVERSION\";
4346
\$ScmLocal                      = \"$BUILDLOCAL\";
4347
\$ScmDeploymentPatch            = \"$DEPLOY_PATCH\";
4348
\$ScmSrcDir                     = \"$Srcdir\";
4349
\$ScmBuildSrc                   = \"$ScmBuildSrc\";
4350
\$ScmExpert                     = \"$Expert\";
261 dpurdie 4351
\$ScmAll                        = \"$All\";
4003 dpurdie 4352
\$ScmNoBuild                    = \"$NoBuild\";
6177 dpurdie 4353
\$ScmBuildUuid                  = \"$BUILD_UUID\";
227 dpurdie 4354
");
4355
 
4356
#.. Alias
4357
#
4358
    $fh->DumpData(
4359
        "\n# Aliases.\n#\n",
4360
        "ScmBuildAliases", \%BUILDALIAS );
4361
 
4362
#.. Products
4363
#
4364
    $fh->DumpData(
4365
        "# Product mapping.\n#\n",
4366
        "ScmBuildProducts", \%BUILDPRODUCT_PARTS );
4367
 
4368
#.. Create ScmBuildPlatforms
4369
#
4370
    my( @platforms_merged, %platform_args ) = ();
4371
 
4372
    UniquePush ( \@platforms_merged, @BUILDPLATFORMS );
4373
 
4374
    foreach my $key ( keys %BUILDPRODUCT ) {
4375
        my( @list ) = split( ' ', $BUILDALIAS{ $key } || '' );
4376
        my( $platform );
4377
 
4378
        foreach my $elem ( @list ) {
4379
            if ( $elem =~ /^--/ ) {             # argument
4380
                HashJoin( \%platform_args, $;, $platform, $elem )
4381
                    if ( defined($platform) );
4382
                next;
4383
            }
4384
            $platform = $elem;                  # platform
4385
            UniquePush( \@platforms_merged, $elem );
4386
        }
4387
    }
4388
 
4389
#.. Create ScmBuildPlatforms
4390
#   Contains per platform options extracted from alias and platform args
4391
#
4392
    my %ScmBuildPlatforms;
4393
    foreach my $key ( @platforms_merged ) {
4394
 
6276 dpurdie 4395
        my $pInfo = $BUILDINFO{$key};
4396
        next if ($pInfo->{NOT_AVAILABLE});
4397
 
227 dpurdie 4398
        my( @arguments ) = ();
4399
        UniquePush( \@arguments, split( /$;/, $BUILDPLATFORMARGS{ $key } ))
4400
            if ( exists $BUILDPLATFORMARGS{ $key } );
4401
 
4402
        UniquePush( \@arguments, split( /$;/, $platform_args{ $key } ))
4403
            if ( exists $platform_args{ $key } );
4404
 
4405
        $ScmBuildPlatforms{$key} = join "$;", @arguments;
4406
    }
4407
 
4408
    $fh->DumpData(
4409
        "# Platform and global argument list.\n#\n",
4410
        "ScmBuildPlatforms", \%ScmBuildPlatforms );
4411
 
6276 dpurdie 4412
#.. Create ScmBuildMatrix
4413
#   Contains information on all the platforms that the package builds for and target machines
4414
#   
4415
    my %ScmBuildMatrix;
4416
    foreach my $key ( keys %BUILDINFO ) {
4417
        my $pInfo = $BUILDINFO{$key};
4418
        next if exists ($pInfo->{BADNAME});
4419
        next if ($pInfo->{NOT_AVAILABLE} > 1);
4420
        Error ("Internal: No MACHTYPE provided for $key") unless exists $pInfo->{MACHTYPE};
4421
        $ScmBuildMatrix{$key} = $pInfo->{MACHTYPE};
4422
    }
227 dpurdie 4423
 
6276 dpurdie 4424
    $fh->DumpData(
4425
        "# Build Matrix.\n#\n",
4426
        "ScmBuildMatrix", \%ScmBuildMatrix );
4427
 
227 dpurdie 4428
# .. Create BuildPkgRules
4429
#
367 dpurdie 4430
#    This is most of the information contained within %PKGRULES, which
227 dpurdie 4431
#    requires additional processing within makelib.
4432
#
367 dpurdie 4433
#   Need the True Path for windows.
4434
#       Some makefile functions (wildcard) only work as expected
4435
#       if the case of the pathname is correct. Really only a problem
4436
#       with badly formed legecy packages where the Windows user
4437
#       guessed at the package format.
4438
#
227 dpurdie 4439
    my %ScmBuildPkgRules;
4440
    foreach my $platform ( keys %PKGRULES )
4441
    {
4442
        foreach my $package ( @{$PKGRULES{$platform}} )
4443
        {
6684 dpurdie 4444
            next if exists $package->{'EXCLUDE'};
227 dpurdie 4445
            my %entry;
4446
 
367 dpurdie 4447
            $entry{ROOT}     = TruePath( $package->{'base'} );
227 dpurdie 4448
            $entry{NAME}     = $package->{'name'};
4449
            $entry{VERSION}  = $package->{'version'};
4450
            $entry{DNAME}    = $package->{'dname'};
4451
            $entry{DVERSION} = $package->{'dversion'};
4452
            $entry{DPROJ}    = $package->{'dproj'};
4453
            $entry{TYPE}     = $package->{'type'};
4454
            $entry{CFGDIR}   = $package->{'cfgdir'} if ( defined( $package->{'cfgdir'} ) );
4455
 
367 dpurdie 4456
            foreach my $dir (qw (TOOLDIRS) )
227 dpurdie 4457
            {
4458
                $entry{$dir} = $package->{$dir} ;
4459
            }
4460
 
367 dpurdie 4461
            my $baselen = length($package->{'base'});
4462
            foreach my $dir (qw (PINCDIRS PLIBDIRS THXDIRS) )
4463
            {
4464
                $entry{$dir} = [];
4465
                foreach my $file ( @{$package->{$dir}} )
4466
                {
4467
                    push @{$entry{$dir}}, substr TruePath($package->{'base'} . $file ), $baselen;
4468
                }
4469
            }
4470
 
227 dpurdie 4471
            push @{$ScmBuildPkgRules{$platform}}, \%entry;
4472
        }
4473
    }
4474
 
4475
    $fh->DumpData(
4476
        "# Imported packages.\n#\n",
4477
        "ScmBuildPkgRules", \%ScmBuildPkgRules );
4478
 
4479
#
4480
#   BUILDPLATFORMS,
4481
#       The value that is saved only contains the active platforms
4482
#
4483
#   DEFBUILDPLATFORMS,
4484
#       The value that is matchs the wildcard specification for Platform 
4485
#       directives.
4486
#
4487
    $fh->DumpData(
4488
        "# A list of platforms active within the view.\n#\n",
4489
        "BUILDPLATFORMS", \@BUILD_ACTIVEPLATFORMS );
4490
 
4491
    $fh->DumpData(
4492
        "# A list of default platforms within the view.\n#\n",
4493
        "DEFBUILDPLATFORMS", \@DEFBUILDPLATFORMS );
4494
 
4495
#
4496
#   BUILDTOOLS
4497
#       A list of toolset extension paths
4498
#
4499
    $fh->DumpData(
4500
        "# A list of paths with toolset extension programs.\n#\n",
4501
        "BUILDTOOLSPATH", \@BUILDTOOLS );
4502
 
4503
#
4504
#   BUILDPLATFORM_PARTS
4505
#       A subset of BUILDINFO exported as BUILDPLATFORM_PARTS
4506
#       This exists only for backward compatability with existing code
4507
#       in external packages ( deployfiles).
4508
#
4509
#   Only save those parts that are part of the current build
4510
#   This will prevent users attempting to build for platforms that have not
4511
#   been correctly constructed.
4512
#
4513
    my %active =  map { ${_} => 1 } @BUILD_ACTIVEPLATFORMS;
4514
    my %active_buildplatform_parts;
4515
    my %active_build_info;
4516
    foreach ( keys %BUILDINFO )
4517
    {
4518
        next unless ( $active{$_} );
4519
        $active_buildplatform_parts{$_} = $BUILDINFO{$_}{PARTS};
4520
        $active_build_info{$_}          = $BUILDINFO{$_};
4521
    }
4522
 
4523
    $fh->DumpData(
4524
        "# Parts of all platforms.\n#\n",
4525
        "BUILDPLATFORM_PARTS", \%active_buildplatform_parts );
4526
#
4527
#   BUILDINFO
4528
#       Complete TARGET Information
4529
#
4530
    $fh->DumpData(
4531
        "# Extended build information.\n#\n",
4532
        "BUILDINFO", \%active_build_info );
4533
 
4534
#
247 dpurdie 4535
#   BUILD_KNOWNFILES
4536
#       All paths are relative to the project root directory
4537
#       ie: The directory that conatins the build.pl file
4538
#
4539
    $fh->DumpData(
4540
        "# Generated Files that may be known when used as Src files.\n#\n",
4541
        "BUILD_KNOWNFILES", \%BUILD_KNOWNFILES );
4542
 
4543
#
227 dpurdie 4544
#   Close out the file
4545
#
4546
    $fh->Close();
363 dpurdie 4547
 
227 dpurdie 4548
}
4549
 
4550
#-------------------------------------------------------------------------------
4551
# Function        : WriteParsedBuildConfig
4552
#
4553
# Description     : Write all the parsed build.pl data to a single file
4554
#                   Its all in there for use
4555
#
4556
# Inputs          : 
4557
#
4558
# Returns         : 
4559
#
4560
sub WriteParsedBuildConfig
4561
{
4562
    my $cfg_file = "$::BUILDINTERFACE/Buildfile.cfg";
4563
    my %cf_build_info = ();
4564
 
4565
    #
4566
    #   Examine the symbol table and capture most of the entries
4567
    #
4568
    foreach my $symname (keys %main::)
4569
    {
4570
        next if ( $symname =~ m/::/  );                 # No Typeglobs
4571
        next if ( $symname =~ m/^cf_build_info/  );     # Not myself
4572
        next unless ( $symname =~ m/^[A-Za-z]/  );      # No system type names
4573
        next if ( $symname =~ m/^SIG$/  );              # Useless
4574
        next if ( $symname =~ m/^ENV$/  );              # Don't keep the user ENV
4575
        next if ( $symname =~ m/^INC$/  );              # Don't keep the INC paths
4576
        next if ( $symname =~ m/^DEFINES/  );           # Don't keep
4577
        next if ( $symname =~ m/^TOOLSETRULES/  );      # Don't keep
4578
 
331 dpurdie 4579
        no strict 'vars';
227 dpurdie 4580
        local *sym = $main::{$symname};
4581
 
331 dpurdie 4582
        $cf_build_info{"\$$symname"} =  $sym if defined $sym;
369 dpurdie 4583
        $cf_build_info{"\@$symname"} = \@sym if @sym;
4584
        $cf_build_info{"\%$symname"} = \%sym if %sym;
331 dpurdie 4585
        use strict 'vars';
227 dpurdie 4586
    }
4587
 
4588
    #
4589
    #   Dump out the configuration information
4590
    #
4591
    my $fh = ConfigurationFile::New( "$cfg_file" );
4592
    $fh->Header( "buildlib (version $::BuildVersion)",
4593
                              "Buildfile configuration" );
4594
    $fh->Dump( [\%cf_build_info], [qw(*cf_build_info)] );
4595
    $fh->Close();
4596
}
4597
 
4598
 
4599
#-------------------------------------------------------------------------------
4600
# Function        : BuildSharedLibFiles
4601
#
4602
# Description     : Create a file in the interface directory that will specify
4603
#                   the locations of shared libraries.
4604
#
4605
#                   Note: Always create a file as makefile targets depend on it.
4606
#
4607
#                   This is a bit ugly.
4608
#
4609
#                   There needs be an association between the build machine and
4610
#                   the target platform. Need to know if the current target is
4611
#                   native to the current build machine. If it is then we can
4612
#                   run tests on the machine and we then need to extend the
4613
#                   search path for the target.
4614
#
4615
#                   The BUILDINFO{EXT_SHARED} is used to control the creation of
4616
#                   the files by specifying the extension of the file.
4617
#
4618
# Inputs          : None
4619
#
4620
# Returns         :
4621
#
4622
sub BuildSharedLibFiles
4623
{
4624
    if ( $ScmHost eq "DOS" || $ScmHost eq "WIN" ) {
4625
        BuildSharedLibFiles_WIN(@_);
4626
 
4627
    } elsif ( $ScmHost eq "Unix" ) {
4628
        BuildSharedLibFiles_Unix(@_);
4629
 
4630
    } else {
4631
        Error("Cannot build. Unknown machine type: $ScmHost",
4632
              "Need WIN, DOS or Unix" );
4633
    }
4634
}
4635
 
4636
#-------------------------------------------------------------------------------
4637
# Function        : BuildSharedLibFiles_WIN
4638
#
4639
# Description     : Implementation of BuildSharedLibFiles for Windows
4640
#
4641
# Inputs          : None
4642
#
4643
sub BuildSharedLibFiles_WIN
4644
{
4645
 
4646
    foreach my $platform ( @BUILD_ACTIVEPLATFORMS )
4647
    {
6504 dpurdie 4648
        my @pathList;
4649
        if (exists $BUILDINFO{$platform}{EXT_SHARED} ) {
4650
            push @pathList, reverse BuildSharedLibFiles_list( $platform, $BUILDINFO{$platform}{EXT_SHARED} );
4651
        }
4652
        push @pathList, @BUILDTOOLS; 
227 dpurdie 4653
 
4654
        #
4655
        #   Create a .bat file for WIN32
4656
        #   This may be consumed by user wrapper programs
4657
        #
229 dpurdie 4658
        #   Features: No Echo
4659
        #             Use of SETLOCAL to prevent pollution of environment
4660
        #
227 dpurdie 4661
        my $fh = ::ConfigurationFile::New( "$BUILDINTERFACE/set_$platform.bat", '--NoEof', '--Type=bat' );
229 dpurdie 4662
        $fh->Write ( "\@echo off\n");
227 dpurdie 4663
        $fh->Header( "Buildlib ($BuildVersion)","Shared Library Paths" );
229 dpurdie 4664
        $fh->Write ( "\nSETLOCAL\n");
6511 dpurdie 4665
        foreach ( @pathList ) {
227 dpurdie 4666
            $_ =~ s~/~\\~g;
4667
            $fh->Write ( "PATH=$_;\%PATH\%\n" );
4668
        }
4669
        $fh->Write ( "\n%*\n" );
229 dpurdie 4670
        $fh->Write ( "\nENDLOCAL\n");
231 dpurdie 4671
        $fh->Write ( "EXIT /B %ERRORLEVEL%\n");
227 dpurdie 4672
        $fh->Close();
4673
 
4674
        #
4675
        #   Create a .sh file for WIN32
4676
        #   This may be consumed by a shell - as used within JATS
4677
        #
4678
        $fh = ::ConfigurationFile::New( "$BUILDINTERFACE/set_$platform.sh", '--NoEof', '--Type=sh' );
4679
        $fh->Header( "Buildlib ($BuildVersion)","Shared Library Paths" );
6511 dpurdie 4680
        foreach ( @pathList ) {
227 dpurdie 4681
            tr~\\/~/~s;
4682
            $fh->Write ( "PATH=$_\\;\$PATH\n" );
4683
        }
287 dpurdie 4684
        $fh->Write ( "\n" . '[ -n "$*" ] && "$@"'  ."\n" );
227 dpurdie 4685
        $fh->Close();
4686
    }
4687
}
4688
 
4689
#-------------------------------------------------------------------------------
4690
# Function        : BuildSharedLibFiles_Unix
4691
#
4692
# Description     : Implementation of BuildSharedLibFiles for Unix
4693
#                   Extend the Shared Library search path via LD_LIBRARY_PATH
5877 dpurdie 4694
#                   
4695
#                   Create sonames for all external shared libraries
227 dpurdie 4696
#
4697
# Inputs          : None
4698
#
4699
sub BuildSharedLibFiles_Unix
4700
{
4701
    foreach my $platform ( @BUILD_ACTIVEPLATFORMS )
4702
    {
6504 dpurdie 4703
        my @unix_paths;
4704
        if ( exists $BUILDINFO{$platform}{EXT_SHARED} ) {
4705
            @unix_paths = BuildSharedLibFiles_list( $platform, $BUILDINFO{$platform}{EXT_SHARED} );
227 dpurdie 4706
 
6504 dpurdie 4707
            #
4708
            #   Create sonames for all shared libraries
4709
            #   Append to the begging of the search list - so that it will rendered last
4710
            #   
4711
            my $sodir = BuildSoNameLinks_Unix($platform, @unix_paths);
4712
            unshift( @unix_paths, $sodir ) if defined $sodir;
4713
        }
5877 dpurdie 4714
 
4715
        #
227 dpurdie 4716
        #   Create a .sh file for Unix
4717
        #
229 dpurdie 4718
        my $file = "$BUILDINTERFACE/set_$platform.sh";
4719
        my $fh = ::ConfigurationFile::New( $file , '--NoEof', '--Type=sh' );
227 dpurdie 4720
        $fh->Header( "Buildlib ($BuildVersion)","Shared Library Paths" );
6511 dpurdie 4721
        foreach ( reverse @unix_paths, @BUILDTOOLS ) {
227 dpurdie 4722
            $fh->Write ( "export LD_LIBRARY_PATH=$_:\$LD_LIBRARY_PATH\n" );
4723
        }
6504 dpurdie 4724
 
4725
        #
4726
        #   Extend the search path to allow tools to be located
6511 dpurdie 4727
        #   Have already extended LD_LIBRARY_PATH to allow for tools shared libaraies 
6504 dpurdie 4728
        #   
4729
        $fh->Write ( "\n# Extend Tool Search Path\n" );
4730
        foreach ( @BUILDTOOLS ) {
4731
            tr~\\/~/~s;
6511 dpurdie 4732
            $fh->Write ( "PATH=$_:\$PATH\n" );
6504 dpurdie 4733
        }
4734
 
275 dpurdie 4735
        $fh->Write ( "\n\"\$\@\"\n" );
227 dpurdie 4736
        $fh->Close();
229 dpurdie 4737
 
4738
        #
4739
        #   Make the file executable under unix
4740
        #
4741
        chmod 0755, $file;
227 dpurdie 4742
    }
4743
}
4744
 
4745
#-------------------------------------------------------------------------------
5877 dpurdie 4746
# Function        : BuildSoNameLinks_Unix 
4747
#
4748
# Description     : Generate soname links for all shared libraries from external
4749
#                   packages.
4750
#                   
4751
#                   There is a bit of a cheat. We don't examine the library to determine
4752
#                   the soname. We simple create all possible sonames to the library
4753
#
4754
# Inputs          : $platform       - Target platform
4755
#                   @paths          - Array of paths to scan for libraries 
4756
#
4757
# Returns         : soLinkDir       - Absolute path to the directory of gernerated
4758
#                                     symlinks
4759
#
4760
sub BuildSoNameLinks_Unix
4761
{
4762
    my ($platform, @paths) = @_;
4763
    my $soLinkDir = catdir($BUILDINTERFACE, 'soLinks', $platform );
4764
 
4765
    Verbose("Create Unix SoName links - $soLinkDir");
4766
    RmDirTree( $soLinkDir );
4767
 
4768
    #
4769
    #   Search provided library paths for shared libaries
4770
    #       These are names of the form *.so.* ie : libz.so.1.2.5
4771
    #
4772
    foreach my $path (@paths)
4773
    {
4774
        foreach my $file (glob(catdir($path, '*.so.*')))
4775
        {
4776
            #
4777
            #   Skip the debug symbol files
4778
            #
4779
            next if $file =~ m~\.debug$~;
4780
            next if $file =~ m~\.dbg$~;
4781
 
4782
            #
4783
            #   Generate all possible sonames by removing .nnnn from the 
4784
            #   end of the file name
4785
            #   
4786
            my $sofile = $file;
4787
            while ($sofile =~ m~(.*)\.\d+$~)
4788
            {
4789
                $sofile = $1;
4790
                unless (-f $sofile) {
4791
                    Verbose2("Need Soname: $sofile");
4792
 
4793
                    #
4794
                    #   Create link from soname to full name
4795
                    #   
4796
                    mkpath ( $soLinkDir ) unless -d $soLinkDir;
4797
                    my $sofilename = $sofile;
4798
                    $sofilename =~ s~.*/~~;
4799
                    $sofilename = catdir($soLinkDir, $sofilename);
4800
                    unless (-f $sofilename) {
4801
                        symlink ($file, $sofilename) || Error ("Cannot create symlink to $sofilename. $!"); 
4802
                    }
4803
                }
4804
            }
4805
        }
4806
    }
4807
 
4808
    #
4809
    #   Return the path the generated soLink dir
4810
    #
4811
    return AbsPath($soLinkDir) if (-d $soLinkDir);
4812
    return undef;
4813
}
4814
 
4815
#-------------------------------------------------------------------------------
227 dpurdie 4816
# Function        : BuildSharedLibFiles_list
4817
#
4818
# Description     : Determine a list of Shared Library paths that can be used
4819
#                   by the current target
4820
#
4821
# Inputs          : $platform       - Current platform
4822
#                   $so             - Shared object extensions
4823
#
4824
# Returns         : List of search paths
4825
#
4826
sub BuildSharedLibFiles_list
4827
{
4828
    my ($platform, $so ) = @_;
4829
    my @paths;
4830
    my @parts = @{$BUILDINFO{$platform}{PARTS}};
4831
 
4832
    #
4833
    #   Paths from the current build
4834
    #       Local directory         - for installed components
4835
    #       Interface directory     - for BuildPkgArchives
4836
    #
4837
    if ( $BUILDLOCAL )
4838
    {
5986 dpurdie 4839
        my @localParts;
4840
        UniquePush \@localParts, $BUILDINFO{$platform}{PLATFORM} , $BUILDINFO{$platform}{PRODUCT}, $BUILDINFO{$platform}{TARGET};
4841
        foreach ( @localParts )
227 dpurdie 4842
        {
4843
            push @paths, AbsPath("$BUILDLOCAL/lib/$_");
4844
        }
4845
    }
4846
 
4847
    foreach ( @parts )
4848
    {
4849
            push @paths, AbsPath("$BUILDINTERFACE/lib/$_");
4850
    }
4851
 
4852
    #
4853
    #   For each LinkPkgArchive
4854
    #
4855
    foreach my $package ( @{$PKGRULES{$platform}} )
4856
    {
4857
        next unless ( $package->{'type'} eq 'link' );
4858
 
4859
        my $base = $package->{'base'};
4860
        for my $path ( @{$package->{'PLIBDIRS'}} )
4861
        {
289 dpurdie 4862
            my @so_libs;
317 dpurdie 4863
            push @so_libs, glob ( "$base$path/*$_") foreach ( ArrayList($so) );
227 dpurdie 4864
            next unless scalar @so_libs;
4865
            push @paths, $base . $path;;
4866
        }
4867
    }
4868
 
4869
    #
4870
    #   Returns paths found
4871
    #
4872
    return @paths;
4873
}
4874
 
4875
#-------------------------------------------------------------------------------
247 dpurdie 4876
# Function        : BuildAddKnownFile
4877
#
4878
# Description     : Save the file as a file that will be known  to the JATS
4879
#                   makefiles. It will be available SRCS, but will not be a
4880
#                   part of any object list.
4881
#
4882
#                   Known Files will be deleted on clobber
4883
#
4884
# Inputs          : $path
4885
#                   $file
289 dpurdie 4886
#                   $noadd                    - Don't add to known
247 dpurdie 4887
#
4888
# Returns         : Path and filename
4889
#
4890
 
4891
sub BuildAddKnownFile
4892
{
289 dpurdie 4893
    my ($path, $file, $noadd) = @_;
247 dpurdie 4894
    $path .= '/'. $file;
2450 dpurdie 4895
    $path =~ tr~/~/~s;
289 dpurdie 4896
    $BUILD_KNOWNFILES {$file} = $path
4897
        unless ( defined($noadd) && $noadd);
4003 dpurdie 4898
 
6133 dpurdie 4899
    ToolsetFiles::AddFile( $path )
3967 dpurdie 4900
        unless ($Clobber);
4901
 
247 dpurdie 4902
    return $path;
4903
}
4904
 
4905
#-------------------------------------------------------------------------------
5969 dpurdie 4906
# Function        : WinPath 
4907
#
4908
# Description     : Covert path to a windows formatted path
4909
#
4910
# Inputs          : One path element
4911
#
4912
# Returns         : One ugly path element
4913
#
4914
 
4915
sub WinFullPath
4916
{
4917
    my ($path) = @_;
4918
    $path = FullPath($path);
4919
    $path =~ tr~\\/~\\~s;
4920
    return $path;
4921
}
4922
 
4923
#-------------------------------------------------------------------------------
4924
# Function        : BuildPropertyPages 
4925
#
4926
# Description     : Create a props file suitable for use by VS2010, VS2012 (possibly others)
4927
#                   Only supported for C/C++ projects
4928
#                   Provide info for:
4929
#                       Include Search paths
4930
#                       Library search paths
4931
#                       Nice Macros 
4932
#
4933
# Inputs          : 
4934
#
4935
# Returns         : 
4936
#
4937
sub BuildPropertyPages
4938
{
4939
    StartBuildPhase();                      # Starting the build phase. No more data collection
5986 dpurdie 4940
    return if $Clobber;
5969 dpurdie 4941
    foreach my $platform ( keys %BUILDINFO )
4942
    {
4943
        next unless $BUILDINFO{$platform}{MSBUILDPROPS};
5986 dpurdie 4944
        my $propsFile = BuildAddKnownFile ($Srcdir, 'jats_'. $BUILDINFO{$platform}{TARGET} . '.props');
4945
 
5969 dpurdie 4946
        Message("BuildPropertyPages: $propsFile");
4947
 
4948
        my %macros;
4949
        my @libpaths;
4950
        my @incpaths;
4951
        my @parts = @{$BUILDINFO{$platform}{PARTS}};
4952
 
4953
        #
4954
        #   Basic definitions
4955
        #   
4956
        $macros{'GBE_ROOT'}     = WinFullPath(".");
4957
        $macros{'GBE_PLATFORM'} = $BUILDINFO{$platform}{PLATFORM};
4958
        $macros{'GBE_PRODUCT'}  = $BUILDINFO{$platform}{PRODUCT};
4959
        $macros{'GBE_TARGET'}   = $BUILDINFO{$platform}{TARGET};
4960
        $macros{'GBE_MACHTYPE'} = $::GBE_MACHTYPE;
4961
        $macros{'GBE_PKGDIR'}   = WinFullPath('./pkg/' . $BUILDNAME_PACKAGE);
4962
        $macros{'GBE_BUILDNAME'}= $BUILDNAME_PACKAGE;
4963
 
4964
        #
4965
        #   Paths from the current build
4966
        #       Local directory         - for installed components
4967
        #       Interface directory     - for BuildPkgArchives
4968
        #
4969
        if ( $BUILDLOCAL )
4970
        {
4971
            my $macroName = 'GBE_LOCALDIR';
4972
            $macros{$macroName} = WinFullPath("$BUILDLOCAL") ;
4973
            $macroName = '$(' . $macroName . ')';
5986 dpurdie 4974
            my @localParts;
4975
            UniquePush \@localParts, $BUILDINFO{$platform}{PLATFORM} , $BUILDINFO{$platform}{PRODUCT}, $BUILDINFO{$platform}{TARGET};
4976
            foreach ( @localParts )
5969 dpurdie 4977
            {
4978
                push @libpaths, catdir($macroName, 'lib', $_);
4979
                push @incpaths, catdir($macroName ,'include' ,$_);
4980
            }
4981
            push @incpaths, catdir($macroName ,'include');
4982
        }
4983
 
4984
        my $macroName = 'GBE_INTERFACEDIR';
4985
        $macros{$macroName} = WinFullPath("$BUILDINTERFACE") ;
4986
        $macroName = '$(' . $macroName . ')';
4987
 
4988
        foreach ( @parts )
4989
        {
4990
                push @libpaths, catdir($macroName, 'lib' , $_);
4991
                push @incpaths, catdir($macroName ,'include' ,$_);
4992
        }
4993
        push @incpaths, catdir($macroName ,'include');
4994
 
4995
        #
4996
        #   For each LinkPkgArchive
4997
        #
4998
        foreach my $package ( @{$PKGRULES{$platform}} )
4999
        {
5000
            next unless ( $package->{'type'} eq 'link' );
5001
 
5002
            my $macroName = 'GBE_PACKAGE_'.$package->{'name'};
5003
            $macros{$macroName} = WinFullPath($package->{'base'}) ;
5004
            $macroName = '$(' . $macroName . ')';
5005
 
5006
            for my $path ( @{$package->{'PLIBDIRS'}} )
5007
            {
5008
                push @libpaths, catdir($macroName, $path);
5009
            }
5010
            for my $path ( @{$package->{'PINCDIRS'}} )
5011
            {
5012
                push @incpaths, catdir($macroName, $path);
5013
            }
5014
        }
5015
 
5016
        my $AdditionalIncludeDirectories = join(';', @incpaths );
5017
        my $AdditionalLibraryDirectories = join(';', @libpaths);
5018
        my $PreprocessorDefinitions = 'JATS=1';
5019
 
5020
        #
5021
        #   Create a props file formatted for VS2012
5022
        #
5023
        open (my $XML, '>', $propsFile) || Error ("Cannot create output file: $propsFile", $!);
5024
 
5025
        my $writer = XML::Writer->new(OUTPUT => $XML, UNSAFE => 0, DATA_INDENT => 4, DATA_MODE => 1);
5026
        $writer->xmlDecl("UTF-8");
5027
        $writer->comment('This file is generated by JATS build');
5028
        $writer->comment('Do not edit this file');
5029
        $writer->comment('Do not version control this file');
5030
        $writer->startTag('Project', "ToolsVersion", "4.0", "xmlns", "http://schemas.microsoft.com/developer/msbuild/2003");
5031
        $writer->emptyTag('ImportGroup', 'Label' , "PropertySheets");
5032
 
5033
        #
5034
        #   Special Macro for handling production/debug libraries
5035
        #
5036
        $writer->startTag('PropertyGroup', 'Label' , "UserMacros", 'Condition', "'\$(Configuration)' == 'Debug'");
5037
        $writer->dataElement('GBE_TYPE', 'D');
5038
        $writer->endTag('PropertyGroup');
5039
 
5040
        $writer->startTag('PropertyGroup', 'Label' , "UserMacros", 'Condition', "'\$(Configuration)' != 'Debug'");
5041
        $writer->dataElement('GBE_TYPE', 'P');
5042
        $writer->endTag('PropertyGroup');
5043
 
5044
        #
5045
        #   Define macros
5046
        #   
5047
        $writer->startTag('PropertyGroup', 'Label' , "UserMacros");
5048
        foreach my $key ( sort keys %macros)
5049
        {
5050
            $writer->dataElement($key, $macros{$key});
5051
        }
5052
        $writer->endTag('PropertyGroup');
5053
        $macros{'GBE_TYPE'}     = 1;
5054
 
5055
        #
5056
        #   Extend the search paths for includes and libaraies
5057
        #   
5058
        #$writer->emptyTag('ItemDefinitionGroup');
5059
        $writer->startTag('ItemDefinitionGroup');
5060
 
5061
        $writer->startTag('ClCompile');
5062
        $writer->dataElement('AdditionalIncludeDirectories', $AdditionalIncludeDirectories . ';%(AdditionalIncludeDirectories)');
5063
        $writer->dataElement('PreprocessorDefinitions', $PreprocessorDefinitions . ';%(PreprocessorDefinitions)');
5064
        $writer->endTag('ClCompile');
5065
 
5066
        $writer->startTag('Link');
5067
        $writer->dataElement('AdditionalLibraryDirectories', $AdditionalLibraryDirectories . ';%(AdditionalLibraryDirectories)');
5068
        $writer->endTag('Link');
5069
        $writer->endTag('ItemDefinitionGroup');
5070
 
5071
        #
5072
        #   Specify all macro names
5073
        #
5074
        $writer->startTag('ItemGroup');
5075
        foreach my $key ( sort keys %macros)
5076
        {
5077
            $writer->startTag('BuildMacro', 'Include' , $key);
5078
            $writer->dataElement('Value', '$(' . $key . ')');
5079
            $writer->endTag('BuildMacro');
5080
        }
5081
 
5082
        #
5083
        #   Close tags and write the XML file
5084
        #
5085
        $writer->endTag('ItemGroup');
5086
        $writer->endTag('Project');
5087
        $writer->end();
5088
    }
5089
}
5090
 
5091
 
5092
#-------------------------------------------------------------------------------
227 dpurdie 5093
# Function        : Usage
5094
#
5095
# Description     : Display program usage information
5096
#
5097
# Inputs          : args            - Text message to display
5098
#
5099
#                   $opt_help       - Level of verbose ness
5100
#
5101
# Returns         : Does not return
5102
#                   This function will exit
5103
#
5104
sub Usage
5105
{
5106
    my( $msg ) = @_;
5107
    my %usage_args;
5108
 
5109
    #
5110
    #   Create a hash of arguments for the pod2usage function
5111
    #
5112
    $usage_args{'-input'} = __FILE__;
5113
    $usage_args{'-exitval'} = 42;
5114
    $usage_args{'-message'} = "\nbuildlib $msg\n" if $msg;
5115
    $usage_args{'-verbose'} = $opt_help < 3 ? $opt_help - 1 : 3 if ( $opt_help );
5116
 
5117
    #
5118
    #   Generate nice help
5119
    #
5120
    pod2usage(\%usage_args);
5121
}
5122
 
5123
#-------------------------------------------------------------------------------
5124
#   Documentation
5125
#
5126
 
5127
=pod
5128
 
361 dpurdie 5129
=for htmltoc    JATS::build
5130
 
227 dpurdie 5131
=head1 NAME
5132
 
361 dpurdie 5133
build - Build Environment and Makefiles
227 dpurdie 5134
 
5135
=head1 SYNOPSIS
5136
 
5137
jats build [options] [command]
5138
 
5139
     [perl buildlib.pl [options] PWD [command]]
5140
 
5141
 Options:
7296 dpurdie 5142
    -help           - Display terse usage
5143
    -help -help     - Display verbose usage
5144
    -man            - Display internal manual
5145
    -verbose[=n]    - Set level of progress verbosity
5146
    -debug[=n]      - Set the debug level
5147
    -cache          - Cache packages in the local dpkg_package cache
5148
    -localcache     - Cache packages into the interface directory
5149
    -cache -cache   - Forced refresh dependent packages in the local cache
5150
    -package        - Ignore packages that are not available and continue
5151
    -nopackages     - Ignore package processing directives
5152
    -forcebuildpkg  - Treat LinkPkgArchive directives as BuildPkgArchive
5153
                      Also suppress the use of symlinks so that the physical
5154
                      file will be copied locally.
5155
    -[no]force      - Force build even if build.pl is not newer
5156
                      Default: -force
5157
    -[no]generic    - Build system sanity test
5158
                      Default: Do not test
5159
    -buildinfo=path - Specify name of the buildinfo file
227 dpurdie 5160
 
5161
 Sticky settings:
331 dpurdie 5162
    -all           - Build for all platforms ignoring GBE_BUILDFILTER
5163
    -expert[=n]    - Relaxing dependency checks on the user makefiles
227 dpurdie 5164
 
5165
 Commands:
2078 dpurdie 5166
    clobber        - Remove generated build system (eg Makefiles).
6133 dpurdie 5167
    interface      - Only (re)build the interface tree.
361 dpurdie 5168
    rootonly       - Only (re)build the root directory.
7296 dpurdie 5169
    buildinfo      - Only generate build system info.
227 dpurdie 5170
 
5171
=head1 OPTIONS
5172
 
5173
=over 8
5174
 
331 dpurdie 5175
=item B<-help>
227 dpurdie 5176
 
5177
Print a brief help message and exits.
5178
 
5179
=item B<-help -help>
5180
 
5181
Print a detailed help message with an explanation for each option.
5182
 
5183
=item B<-man>
5184
 
5185
Prints the manual page and exits.
5186
 
331 dpurdie 5187
=item B<-verbose[=n]>
227 dpurdie 5188
 
261 dpurdie 5189
Increases program output.
227 dpurdie 5190
 
261 dpurdie 5191
If an argument is provided, then it will be used to set the level, otherwise the
5192
existing level will be incremented. This option may be specified multiple times.
227 dpurdie 5193
 
261 dpurdie 5194
=item B<-debug>
5195
 
227 dpurdie 5196
Increases program output. Enable internal debugging messages to generate detailed
5197
progress information.
5198
 
261 dpurdie 5199
If an argument is provided, then it will be used to set the level, otherwise the
5200
existing level will be incremented. This option may be specified multiple times.
5201
 
331 dpurdie 5202
=item B<-cache>
227 dpurdie 5203
 
6619 dpurdie 5204
This option will cause dependent packages to be cached in the users local
5205
dpkg_archive cache as defined via GBE_DPKG_CACHE
227 dpurdie 5206
 
5207
If the option is used twice then the packages will be forcibly refreshed.
5208
 
6619 dpurdie 5209
=item B<-localcache>
5210
 
5211
This option will cause dependent packages to be cached into the interface 
5212
directory. This option simplifies the use of a cache when building single
5213
packages.
5214
 
5215
If the option is used twice then the packages will be forcibly refreshed.
5216
 
331 dpurdie 5217
=item B<-package>
227 dpurdie 5218
 
5219
This option will cause the build process to ignore packages that cannot be
5220
located. The package build may fail at a later stage.
5221
 
5222
This option is used by the Auto Build Tool to handle packages that may not be
5223
needed in all builds.
5224
 
2078 dpurdie 5225
=item B<-nopackage>
5226
 
5227
This options will cause all the directives that process external packages to be
5228
ignored.
5229
 
5230
This directive has limited use. It can be used in conjunction with the
5231
'interface' build command in order to create Version Information files in a
5232
sandbox where the required packages do not yet exist.
5233
 
331 dpurdie 5234
=item B<-forcebuildpkg>
227 dpurdie 5235
 
5236
This option will force LinkPkgArchive directives to be treated as
5237
BuildPkgArchive directives. The result is that the 'interface' directory will be
5238
populated with the contents of all dependent packages. Moreover, on a Unix
5239
machine, the files will be copied and not referenced with a soft link.
5240
 
5241
This may be useful for:
5242
 
5243
=over 8
5244
 
361 dpurdie 5245
=item *
227 dpurdie 5246
 
361 dpurdie 5247
Remote Development
227 dpurdie 5248
 
361 dpurdie 5249
=item *
227 dpurdie 5250
 
361 dpurdie 5251
Collecting header files for scanning
5252
 
5253
=item *
5254
 
5255
Local modification of files for test/debug/development
5256
 
227 dpurdie 5257
=back
5258
 
331 dpurdie 5259
=item B<-[no]force>
227 dpurdie 5260
 
331 dpurdie 5261
The '-noforce' option will only perform a build, if the build.pl file
363 dpurdie 5262
has been modified, or the buildfilter has changed, since the last build.
331 dpurdie 5263
 
363 dpurdie 5264
The default operation will always force a build.
331 dpurdie 5265
 
4778 dpurdie 5266
=item B<-[no]generic>
5267
 
5268
If used, this option will perform a sanity test on the build type. If set to 
5269
Generic then the build must be a GENERIC build. If set to noGeneric then the build
5270
must not be a GENERIC build.
5271
 
5272
The default is to not perform the test.
5273
 
5274
This option is intended to be used by the automated build system.
5275
 
7296 dpurdie 5276
=item B<-buildinfo>
5277
 
5278
This option is only used in conjunction with the 'buildinfo' command. It will specify 
5279
the path of a file to write the build information. The dafault value is 'BuildInfo.properties'.
5280
 
5281
This option, by itslef, will not invoke the buildinfo mode.
5282
 
331 dpurdie 5283
=item B<-all>
5284
 
227 dpurdie 5285
This option will cause the build process to generate makefiles for all
5286
possible build targets ignoring the use of GBE_BUILDFILTER.
5287
 
5288
This option is sticky. Once used in a build it will be retained when makefiles
5289
are rebuilt.
5290
 
331 dpurdie 5291
=item B<-expert[=n]>
227 dpurdie 5292
 
5293
This option causes the generation of makefiles with relaxed dependancy checks.
5294
 
261 dpurdie 5295
If an argument is provided, then it will be used to set the level, otherwise a
5296
level of '1' will be set.
5297
 
227 dpurdie 5298
The makefiles will have no dependancy between the makefiles and the JATS build
5299
files or the users makefile. If the user's makefile.pl is changed then JATS
5300
will not detect the change and will not rebuild the makefiles. The user manually
5301
force the rebuild with the command 'jats rebuild'.
5302
 
5303
This option should be used with care and with full knowledge of its impact.
5304
 
5305
This option is sticky. Once used in a build it will be retained when makefiles
363 dpurdie 5306
are rebuilt. It will only be lost when the next 'jats build' is performed.
227 dpurdie 5307
 
261 dpurdie 5308
The effect of the option can be changed when the makefiles are processed. This
5309
option simply sets the default' mode of operation.
5310
 
227 dpurdie 5311
=item B<interface>
5312
 
6133 dpurdie 5313
This command will only build, or rebuild, the 'interface' directory.
227 dpurdie 5314
 
261 dpurdie 5315
This command will not build, or rebuild, the root directory. The build
227 dpurdie 5316
process will not recurse through the subdirectories creating makefiles.
5317
 
261 dpurdie 5318
=item B<rootonly>
5319
 
6133 dpurdie 5320
This command will only build, or rebuild, the 'interface' directory and 
5321
the root-level makefiles.
261 dpurdie 5322
 
5323
The build process will not recurse through the subdirectories creating
5324
makefiles. These can be made on-demand by jats if a 'make' command is issued.
5325
 
7296 dpurdie 5326
 
5327
=item B<buildinfo>
5328
 
5329
This command is used by the build system to generate information about the
5330
build. It will create a file with the following information.
5331
 
5332
=over 4
5333
 
5334
=item * All platforms that the package can be built for.
5335
 
5336
=item * All platforms that the package will be built for with the current build filter
5337
 
5338
=item * Platforms that have been specifically excluded from the build
5339
 
5340
=item * Platforms not known to JATS
5341
 
5342
=item * Toolset build information
5343
 
5344
=item * Generic build information
5345
 
5346
=item * Indication of production and debug builds
5347
 
5348
=item * JAVA version specified
5349
 
5350
=back
5351
 
5352
 
5353
 
227 dpurdie 5354
=item B<clobber>
5355
 
5356
This command will remove generated build system files and directories.
5357
 
5358
=back
5359
 
5360
=head1 DESCRIPTION
5361
 
5362
The default build process will parse the user's build.pl file and create the
5363
'interface' directory before creating makefiles for each target platform.
5364
 
5365
The 'build' process simply generates the build sandbox. It does not invoke the
5366
generated makefiles. This must be done by the user in a different phase.
5367
 
5368
The 'build' process need only be invoked if the build.pl file has changed. The
5369
generated makefiles will detected changes to the makefile.pl's and cause them to
5370
be generated as required. The 'build' step sets up the sandboxes external
5371
environment.
5372
 
5373
=head1 INVOCATION
5374
 
5375
This perl library (buildlib.pl) is not designed to be invoked directly by the
5376
user. It should be invoked through a 'build.pl' file. Moreover, for historical
5377
reasons, the build.pl is not easily invoked. It is best to only invoke the
5378
'build' process via the JATS wrapper scripts : jats.bat or jats.sh.
5379
 
331 dpurdie 5380
The build.pl file must be invoked with one fixed arguments, followed by user
227 dpurdie 5381
options and subcommands
5382
 
5383
=over 8
5384
 
361 dpurdie 5385
=item   1
227 dpurdie 5386
 
361 dpurdie 5387
The current working directory
5388
 
227 dpurdie 5389
This could have been derived directly by the program, rather than having it
5390
passed in.
5391
 
361 dpurdie 5392
=item   2
227 dpurdie 5393
 
361 dpurdie 5394
Options and commands may follow the first two mandatory arguments.
5395
 
227 dpurdie 5396
=back
5397
 
5398
The build.pl file must 'require' the buildlib.pl and makelib.pl. The preferred
5399
code is:
5400
 
5401
=over 8
5402
 
5403
    build.pl: First statements
5404
    $MAKELIB_PL     = "$ENV{ GBE_TOOLS }/makelib.pl";
5405
    $BUILDLIB_PL    = "$ENV{ GBE_TOOLS }/buildlib.pl";
5406
 
5407
    require         "$BUILDLIB_PL";
5408
    require         "$MAKELIB_PL";
5409
 
5410
=back
5411
 
5412
=cut
5413
 
5414
1;