Subversion Repositories DevTools

Rev

Rev 7321 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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