Subversion Repositories DevTools

Rev

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