Subversion Repositories DevTools

Rev

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

Rev Author Line No. Line
363 dpurdie 1
########################################################################
2
# Copyright (C) 1998-2011 Vix Technology, 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;
26
use Pod::Usage;
261 dpurdie 27
use Getopt::Long;
305 dpurdie 28
use File::Path;
227 dpurdie 29
 
30
our $BuildVersion           = "2.1.0";
31
 
32
#.. Switchs
33
#
34
our $ScmBuildlib            = 0;
35
our $ScmBuildSrc            = "";
36
 
37
our $CmdSwitch              = "";
38
our $Clobber                = 0;
39
our $Archive                = 0;
40
our $Interface              = 0;
41
our $RootOnly               = 0;
42
our $Perms                  = 0;
43
our $Expert                 = 0;
44
our $All                    = 0;
45
our $Nolog                  = 0;
5109 dpurdie 46
our $Cache                  = $ENV{GBE_DPKG_CACHE_CTL} || 0;
261 dpurdie 47
our $NoPackageError         = 0;
227 dpurdie 48
our $ForceBuildPkg          = 0;
49
our $Srcdir                 = "";               # default source root
331 dpurdie 50
our $ForceBuild             = 1;
2078 dpurdie 51
our $IgnorePkgs             = 0;
4778 dpurdie 52
our $GenericBuild           = undef;            # Build System Generic Build Test
227 dpurdie 53
 
54
#.. Public symbols, referenced by many build.pl implementations
55
#
56
our $BUILDPREVIOUSVERSION   = "0.0.0";          # BuildPreviousVersion()
57
our @BUILDPLATFORMS         = ();               # BuildPlatforms()
58
our %BUILDINFO              = ();               # BuildInfo
59
our @DEFBUILDPLATFORMS      = ();
60
our %BUILDPLATFORMARGS      = ();
61
our @BUILD_ACTIVEPLATFORMS  = ();
62
our @BUILDSUBDIRS           = ();               # BuildSubDir()
63
our @BUILDSETENV            = ();               # BuildSetenv()
64
our $BUILDINTERFACE         = "";               # BuildInterface()
65
our $BUILDLOCAL             = "";               # BuildInterface()
66
our $BUILDDIRTREE           = "";               # BuildDirTree()
241 dpurdie 67
our @BUILD_BADNAME          = ();               # Unknown platforms
4551 dpurdie 68
our @GENERIC_TARGETS        = ();               # Generic targets - only one allowed    
227 dpurdie 69
 
70
our $BUILDNAME              = "";               # BuildName()
71
our $BUILDVERSION           = "";               # BuildName()
72
our $BUILDNAME_PACKAGE;                         # Name
73
our $BUILDNAME_VERSION;                         # Version
74
our $BUILDNAME_PROJECT;                         # Project(optional)
359 dpurdie 75
our $BUILDNAME_SUFFIX;                          # Project (available)
227 dpurdie 76
our $DEPLOY_PATCH           = 0;                # Deplyment patch number
77
 
78
our %BUILDALIAS_DELAY       = ();               # Delayed aliases
79
our %BUILDALIAS_TARGETS     = ();               # BuildAlias from --Targets
80
our %BUILDALIAS             = ();               # BuildAlias
81
our %BUILDPRODUCT           = ();               # BuildProduct
82
our %BUILDPRODUCT_PARTS     = ();               # BuildProduct parts
83
our %PKGRULES               = ();               # Package include and link rules
84
our @BUILDTOOLS             = ();               # Extended tool path
85
our $BUILDPHASE             = 0;                # In Build Phase
86
our @CLOBBERDIRS            = ();               # Directories to clobber
375 dpurdie 87
our @REMOVEDIRS             = ();               # Directories to remove - if empty
247 dpurdie 88
our %BUILD_KNOWNFILES       = ();               # Files that will be known
5679 dpurdie 89
our @BUILDEXCLUDE           = ();               # Platforms to be excluded
227 dpurdie 90
 
333 dpurdie 91
our $Makelib                = "";
263 dpurdie 92
our $GBE_CORE;                                  # Root of JATS
93
our $InterfaceVersion;                          # Interface directory format version
3967 dpurdie 94
our $ScmRoot;                                   # Package Root
263 dpurdie 95
our $ScmInterface;                              # Interface directory
363 dpurdie 96
our $ScmBuildFilter;                            # Build Filter when build was created
4003 dpurdie 97
our $NoBuild                = 0;                # Dummy Build under ABT only
227 dpurdie 98
 
263 dpurdie 99
 
227 dpurdie 100
my  $DeleteDPACKAGE         = 0;                # Must clobber DPACKAGE
305 dpurdie 101
my  $build_source_pkg       = 0;                # Flag to build source package
227 dpurdie 102
my  $opt_help               = 0;
359 dpurdie 103
my  $sandbox_exact          = 0;                # Exact or in-exact sandbox
227 dpurdie 104
 
105
BuildLibInit();
106
 
107
sub BuildLibInit
108
{
109
 
110
#.. Set environment
111
#
331 dpurdie 112
    EnvImport( 'GBE_VERSION' );
113
    EnvImport( 'GBE_BIN' );
114
    EnvImport( 'GBE_CORE' );
115
    EnvImport( 'GBE_PERL' );
116
    EnvImport( 'GBE_TOOLS' );
117
    EnvImport( 'GBE_CONFIG' );
118
    EnvImport( 'GBE_DPKG' );
119
    EnvImport( 'GBE_MACHTYPE' );
120
    EnvImport( 'USER' );
121
    EnvImport( 'GBE_HOSTNAME');
122
    EnvImport( 'GBE_DRV' )
123
        if ( $ScmHost ne 'Unix' );            # DOS or WIN special
227 dpurdie 124
 
4688 dpurdie 125
    EnvImportOptional ( 'GBE_DPKG_REPLICA','' );
227 dpurdie 126
    EnvImportOptional ( 'GBE_DPKG_STORE','' );
127
    EnvImportOptional ( 'GBE_DPKG_CACHE','' );
128
    EnvImportOptional ( 'GBE_DPKG_LOCAL','' );
129
    EnvImportOptional ( 'GBE_DPKG_SBOX' ,'' );
313 dpurdie 130
    EnvImportOptional ( 'GBE_DPLY'      ,'' );
341 dpurdie 131
    EnvImportOptional ( 'GBE_SANDBOX'   ,'' );
227 dpurdie 132
 
133
    EnvImportOptional ( 'GBE_PLATFORM' );           # optional PLATFORM filter
134
    EnvImportOptional ( 'GBE_BUILDFILTER' );        # optional BUILD filter       
135
    EnvImportOptional ( 'GBE_ABT' );                # optional ABT flags          
136
 
137
#.. Common stuff
138
#
139
    require "$::GBE_TOOLS/common.pl";
331 dpurdie 140
    CommonInit( 'buildlib' );
227 dpurdie 141
    Debug( "Version:   $BuildVersion" );
279 dpurdie 142
    Require( "$::GBE_CONFIG/PLATFORM", "PLATFORM_CFG.PM"  );
227 dpurdie 143
 
144
#.. Parse command line
145
#
146
    $ScmBuildSrc = $0;                          # Name of the build file
331 dpurdie 147
    $Cwd = shift @ARGV;
227 dpurdie 148
    $Cwd =~ tr~\\/~/~s;;                        # Need / in path, Remove doubles
3967 dpurdie 149
    $::ScmRoot = StripDrive($Cwd);
333 dpurdie 150
    $Makelib = shift @ARGV;                     # Only for legacy build.pl files
227 dpurdie 151
 
261 dpurdie 152
    Verbose ("Command Line: @ARGV");
313 dpurdie 153
    my $result = GetOptions( "help|h:+"      => \$opt_help,
154
                             "man:3"         => \$opt_help,
155
                             "debug:+"       => \$::ScmDebug,
156
                             "verbose:+"     => \$::ScmVerbose,
157
                             "expert:1"      => \$Expert,
158
                             "all"           => \$All,
159
                             "nolog"         => \$Nolog,
331 dpurdie 160
                             "cache:+"       => \$Cache,
313 dpurdie 161
                             "package"       => \$NoPackageError,
2078 dpurdie 162
                             "nopackages"    => \$IgnorePkgs,
313 dpurdie 163
                             "forcebuildpkg" => \$ForceBuildPkg,
331 dpurdie 164
                             "force!"        => \$ForceBuild,
4778 dpurdie 165
                             "generic!"      => \$GenericBuild,
313 dpurdie 166
                             );
261 dpurdie 167
    Usage() if ( $opt_help || !$result );
227 dpurdie 168
 
331 dpurdie 169
    Debug( "Host:          ", $ScmHost );
170
    Debug( "Cwd:           ", $Cwd );
333 dpurdie 171
    Debug( "Makelib:       ", $Makelib );
331 dpurdie 172
    Debug( "BuildFile:     ", $ScmBuildSrc );
173
    Debug( "Debug:         ", $::ScmDebug );
174
    Debug( "Verbose:       ", $::ScmVerbose );
175
    Debug( "Expert:        ", $Expert );
176
    Debug( "All:           ", $All );
177
    Debug( "Nolog:         ", $Nolog );
178
    Debug( "Cache:         ", $Cache );
179
    Debug( "package:       ", $NoPackageError );
180
    Debug( "ForcePkg  :    ", $ForceBuildPkg );
181
    Debug( "ForceBuild :   ", $ForceBuild );
4778 dpurdie 182
    Debug( "IgnorePkgs :   ", $IgnorePkgs );
183
    Debug( "GenericTest :  ", $GenericBuild );
227 dpurdie 184
 
185
#.. Command
186
#
3967 dpurdie 187
 
188
    $CmdSwitch = (lc shift @ARGV) if @ARGV;
331 dpurdie 189
    Debug( "CmdSwitch:     ", $CmdSwitch );
227 dpurdie 190
 
331 dpurdie 191
    if ( $CmdSwitch )
192
    {
193
        if ( $CmdSwitch eq "interface" ) {
194
            $Interface      = 1;
227 dpurdie 195
 
331 dpurdie 196
        } elsif ( $CmdSwitch eq "rootonly" ) {
197
            $RootOnly       = 1;
227 dpurdie 198
 
331 dpurdie 199
        } elsif ( $CmdSwitch eq "clobber" ) {
200
            $Clobber        = 1;
227 dpurdie 201
 
331 dpurdie 202
        } elsif ( $CmdSwitch eq "help" || $CmdSwitch eq "usage" ) {
203
            $opt_help = 1;
204
            Usage();
227 dpurdie 205
 
331 dpurdie 206
        } elsif ( $CmdSwitch eq "changelog" ) {
207
            if ( -d "CVS" )                         # CVS support subdir
208
            {
209
                System( "$::GBE_PERL $::GBE_TOOLS/cvs2cl.pl --tags --branches --revisions --day-of-week" )
210
            }
211
            exit(1);
227 dpurdie 212
 
331 dpurdie 213
        } else {
214
            Usage( "(E) build. Unknown command \"$CmdSwitch\"" );
215
        }
216
    }
227 dpurdie 217
 
331 dpurdie 218
    #
341 dpurdie 219
    #   If we are not performing a ForceBuild, then we don't need to continue
220
    #   We have updated the interface directory with BuildPkgArchive
221
    #   information.
331 dpurdie 222
    #
341 dpurdie 223
    unless ( $::GBE_SANDBOX )
331 dpurdie 224
    {
341 dpurdie 225
        TestForForcedBuild();
227 dpurdie 226
    }
227
 
228
    #
229
    #   Must inform makelib that its running under buildlib
230
    #
231
    $ScmBuildlib = 1;
232
 
233
    #
234
    #   In clobber mode System commands will not force termination
235
    #   otherwise, within build.pl, a failed system command will die.
236
    #
237
    SystemConfig ('UseShell' => 1,
283 dpurdie 238
                  'ExitOnError' => ($Clobber == 0) );
5109 dpurdie 239
 
240
    #
241
    #   Capture messages while processing directives
242
    # 
243
    StartCapture(1) 
244
        unless ($Clobber);
227 dpurdie 245
}
246
 
247
 
248
#-------------------------------------------------------------------------------
249
# Function        : Log
250
#
251
# Description     : Internal function to generate a log file of the build process
341 dpurdie 252
#                   The function will print its arguments to the screen and a log file
227 dpurdie 253
#
254
# Inputs          : Arguments will be printed
255
#
256
# Returns         : Nothing
257
#
258
sub Log
259
{
260
    if ( ! $Clobber )
261
    {
261 dpurdie 262
        print "@_\n";
263
        FileAppend ('build.log', \@_ );
227 dpurdie 264
    }
265
}
266
 
267
#-------------------------------------------------------------------------------
268
# Function        : BuildSubDir
269
#
270
# Description     : Specify one or more directories in which makefile.pl's can be
271
#                   found to be processed.
272
#
273
#                   This function will flag the build 'src' dir.
274
#                   This will be the first directory specified UNLESS there
275
#                   is a 'src' directory in the list
276
#
277
#                   The function may be called multiple times.
278
#
279
# Inputs          : NewDirs             - An array of directories
280
#
281
# Returns         : Nothing
282
#
283
 
284
sub BuildSubDir
285
{
286
    my( @NewDirs );
287
 
288
    @NewDirs = map { split /\s+/ } @_;
289
    @NewDirs = grep { defined $_ } @NewDirs;
290
 
291
    Debug( "BuildSubDir(@NewDirs)" );
292
 
293
    foreach my $ThisDir ( @NewDirs )
294
    {
295
        unless ( $Clobber )
296
        {
2450 dpurdie 297
            $ThisDir =~ s~/+$~~;
227 dpurdie 298
            if ( $ThisDir eq "." )
299
            {
300
                Error( "BuildSubDir() cannot specify the current directory (.)",
301
                       "The makefile.pl in the root directory is included in all makefile.pl's" );
302
            }
303
 
304
            if ( $ThisDir =~ m~\\~)
305
            {
306
                Warning ("BuildSubDir contains a '\\' character: $ThisDir" );
307
            }
308
            if ( grep /^$ThisDir$/, @BUILDSUBDIRS )
309
            {
310
                Warning( "BuildSubDir() duplicate subdirectory ignored '$ThisDir'." );
311
                next;
312
            }
313
            if ( ! ( -e $ThisDir and -d $ThisDir ) )
314
            {
315
                Error( "BuildSubDir() non-existent subdirectory: '$ThisDir'." );
316
            }
317
            if ( ! -f $ThisDir . '/makefile.pl' )
318
            {
319
                Error( "BuildSubDir() makefile.pl not found in subdirectory: '$ThisDir'." );
320
            }
321
 
322
            push( @BUILDSUBDIRS, $ThisDir );
323
        }
324
 
325
        #
326
        #   Capture the first source directory mentioned
327
        #   This will be used as the root of the build
328
        #
329
        #   If there is a Src directory then use this
330
        #
331
        $Srcdir = $ThisDir
332
            if ( $ThisDir =~ m/^src$/i );
333
        $Srcdir = $ThisDir
334
            unless ( $Srcdir );
335
    }
336
}
337
 
338
#-------------------------------------------------------------------------------
339
# Function        : BuildAlias
340
#
341
# Description     : Create an alias for multiple targets
342
#                   The default operations will:
343
#                       Add the alias as a default platform (* in the makefile.pl)
344
#                       Perform an implicit BuildPlatform for the alias targets
345
#
346
#                   In hindsight this was not good. Options modify the behaviour
347
#                   Options:
348
#                       --NotDefault    The alias will not be a part of the default
349
#                                       platform for the makefile.pls
350
#                       --Define        Simply define text substitution
351
#                                       Do not implicitly create platforms
352
#                       --Target        Accumulate platforms with specified targets
353
#                                       Complete alias determination is delayed
354
#                                       The named targets are specified as an alias
355
#                                       until the calculation is done
356
#
357
# Inputs          : alias[,--options]   comma seperated options
358
#                   arguments           alias arguments; platforms or targets
359
#
360
# Returns         : Nothing
361
#
362
sub BuildAlias
363
{
364
    my( $alias, @arguments ) = @_;
365
    my $notdefault;
366
    my $define;
367
    my $target_mode;
368
 
369
    Debug( "BuildAlias($alias, @arguments)" );
370
    Error ("BuildAlias: No platforms specified") unless ( @arguments );
371
    Error( "BuildAlias() must appear before BuildName()..." ) if ( $BUILDNAME );
372
 
373
    #   Parse attributes
374
    #
375
    my ( @attrs ) = split( ',', $alias );
376
 
377
    $alias = "";
378
    foreach ( @attrs ) {
379
        if ( /^--/ ) {
380
            if ( /^--NotDefault$/ ) {
381
                $notdefault = 1;
382
 
383
            } elsif ( /^--Define$/ ) {
384
                $define = 1;
385
 
386
            } elsif ( /^--Target$/ ) {
387
                $target_mode = 1;
388
 
389
            } else {
390
                Warning( "BuildAlias() unknown attribute: $_ -- ignored" );
391
            }
392
 
393
        } else {
5262 dpurdie 394
            Error( "BuildAlias() multiple alias specifications", "First: $alias and now $_" )
227 dpurdie 395
                if ( $alias ne "" );
396
            $alias = $_;
397
        }
398
    }
399
    Error( "BuildAlias() missing alias specifications" )
400
        if ( $alias eq "" );
401
 
402
 
403
    #
404
    #   If we need to recalculate the alias based on targets, then tag the alias
405
    #   to be processed
406
    #
407
    $BUILDALIAS_TARGETS{ $alias } = ''
408
        if ( $target_mode );
409
 
410
    #   Define alias
411
    #
4551 dpurdie 412
    if ( PlatformConfig::checkBuildAvailability($alias) == 2 )
227 dpurdie 413
    {
4551 dpurdie 414
        Error( "BuildAlias() cannot create an alias named $alias", "That name is reserved for generic targets" );
227 dpurdie 415
    }
416
    elsif ( $alias ne quotemeta( $alias ) )
417
    {
418
        Warning( "BuildAlias() alias '$alias' contains invalid characters -- ignored" );
419
    }
420
    elsif ( $BUILDALIAS{ $alias } )
421
    {
422
        Warning( "BuildAlias() duplicate alias '$alias' -- alias ignored" );
423
    }
424
    else
425
    {
426
        #
427
        #   Expand alias UNLESS using --Target.
428
        #   The --Target is a real target and not a subject to alias expansion
429
        #   This solves order dependancy problems.
430
        #
431
        @arguments = ExpandPlatforms( @arguments )
432
            unless $target_mode;
433
 
434
        my $platform = "";                   # current platform
435
        my @pargs = ();                      # current args
436
 
437
        #
438
        #   Process the expanded arguments
439
        #   Collect arguments and process when a new platform is discovered
440
        #
441
        foreach my $arg ( @arguments, '++' )
442
        {
443
            if ( $arg =~ /^--/ )
444
            {
445
                push @pargs, $arg;
446
                next;
447
            }
448
            else
449
            {
450
                #
451
                #   Start of a platform
452
                #   Process previous data, once a platform has been seen
453
                #
454
                if ( $platform )
455
                {
456
                    #   Add arguments to BUILDALIAS as we see them
457
                    #
458
                    HashJoin( \%BUILDALIAS, ' ', $alias, $platform );
459
                    HashJoin( \%BUILDALIAS, ' ', $alias, grep(!/^--Uses=/, @pargs) );
460
 
461
                    #
462
                    #   The BuildAlias can also define a platform.
463
                    #   (Sounded like a good idea at the time!)
464
                    #
465
                    unless ( $define || $target_mode )
466
                    {
467
                        push @pargs, '--NotDefault' if ( $notdefault );
468
                        push @pargs, '--FunctionName=BuildAlias';
469
                        BuildPlatforms( $platform, @pargs );
470
                    }
471
                }
472
 
473
                #
474
                #   Start collecting args for the next platform
475
                #
476
                @pargs = ();
477
                $platform = $arg;
478
            }
479
        }
480
    }
481
}
482
 
483
 
484
#-------------------------------------------------------------------------------
485
# Function        : Process_TargetAlias
486
#
487
# Description     : Post Process the --Target option for the build alias
488
#                   Filter all platforms and extract those with a matching targets
489
#
490
# Inputs          : None
491
#
492
# Returns         : Nothing
493
#
494
sub Process_TargetAlias
495
{
496
 
497
    #
498
    #   Merge any delayed aliases with the complete set of alias
499
    #   Delayed alias are not used in expansions during the processing
5410 dpurdie 500
    #   of platforms and targets, but can be used to pick up errors
227 dpurdie 501
    #
502
    while ( my($key,$value) = each(%BUILDALIAS_DELAY) )
503
    {
504
        if ( exists($BUILDALIAS{$key}) )
505
        {
5410 dpurdie 506
            abtWarning("BuildAlias() duplicates internal alias '$key'");
227 dpurdie 507
            next;
508
        }
509
        $BUILDALIAS{$key} = $value;
510
    }
5410 dpurdie 511
    ErrorDoExit();
227 dpurdie 512
 
513
    foreach my $alias ( keys %BUILDALIAS_TARGETS )
514
    {
515
        Debug( "BuildTargetAlias($alias)" );
516
 
517
        #
518
        #   Replace the existing alias - it has done its JOB
519
        #
520
        my $arguments = delete $BUILDALIAS{ $alias } ;
521
 
522
        foreach my $arg ( split / /, $arguments )
523
        {
524
            if ( $arg =~ /^--/ )                # argument
525
            {
526
                #   Add arguments to BUILDALIAS as we see them
527
                #
528
                HashJoin( \%BUILDALIAS, ' ', $alias, $arg );
529
                next;
530
            }
531
 
532
            foreach my $platform ( keys %BUILDINFO )
533
            {
534
                foreach my $element ( qw (TARGET BASE ) )
535
                {
536
                    my $target = $BUILDINFO{$platform}{$element};
537
                    if ( $target && $target eq $arg )
538
                    {
539
                        HashUniqueJoin( \%BUILDALIAS, ' ', $alias, $platform );
540
                        Debug( "BuildTargetAlias: $alias, $target -> $platform" );
541
                    }
542
                }
543
            }
544
        }
545
    }
546
}
547
 
548
#-------------------------------------------------------------------------------
549
# Function        : BuildProduct
550
#
551
# Description     : Create a family of Platforms with a common product line
552
#                   ie: Create two flavors of the TP5, one based on the MOSF and
553
#                   the othe based on the MOS68 toolset.
554
#
555
# Inputs          : $product[,opts]+    The name of the product
556
#                                       This will be the base name for the family
557
#                                       Allowed options are:
558
#                                           --NotDefault    : This is not a default build platform
559
#                                           --Uses=xxx      : All use another platform
5115 dpurdie 560
#                                           --Alias=yyy     : All alias to this name
227 dpurdie 561
#
562
#                   platforms           One or more root platforms, with options
563
#                                       The platform is macro expanded.
564
#                                       Options may be a part of the platform or
565
#                                       distinct.
566
#
567
# Returns         :
568
#
569
 
570
sub BuildProduct
571
{
572
    my( $product, @arguments ) = @_;
573
    my $notdefault = 0;
574
    my @uses = ();
5115 dpurdie 575
    my @alias = ();
227 dpurdie 576
 
577
    Debug( "BuildProduct($product, @arguments)" );
578
    Error( "BuildProduct must appear before BuildName()..." )
579
        if ( $BUILDNAME ne "" );
580
 
581
    #   Parse attributes
582
    #
583
    my( @attrs ) = split( ',', $product );
584
 
585
    $product = "";
586
    foreach ( @attrs ) {
587
        if ( /^--/ ) {
588
            if ( /^--NotDefault$/ ) {
589
                $notdefault++;
590
 
591
            } elsif ( /^--Uses=(.*)/ ) {
592
                UniquePush (\@uses, $1);
593
 
5115 dpurdie 594
            } elsif ( /^(--Alias=.*)/ ) {
595
                UniquePush (\@alias, $1);
596
 
227 dpurdie 597
            } else {
598
                Warning( "BuildProduct() unknown attribute: $_ -- ignored" );
599
            }
600
 
601
        } else {
602
            Error( "BuildProduct() multiple product specifications not allowed" )
603
                if ( $product ne "" );
604
            $product = $_;
605
        }
606
    }
607
 
608
    #
609
    #   Sanity test
610
    #
611
    Error( "BuildProduct() missing product specifications" )
612
        if ( $product eq "" );
613
 
614
    Error( "BuildProduct() product '$product' contains invalid characters" )
615
        if ( $product ne quotemeta( $product ) );
616
 
617
    Error( "BuildProduct() duplicate product '$product'" )
618
        if ( $BUILDPRODUCT{ $product } );
619
 
620
    Error( "BuildProduct() duplicate alias '$product'" )
621
        if ( $BUILDALIAS{ $product } );
622
 
623
    #
624
    #   Expand the user specified targets to allow the use of BuildAlias
625
    #   The (bad) side effect of this is that target options get reorganised
626
    #       PLATFORM,--Uses=ANOTHER  ==> PLATFORM --Uses=ANOTHER
627
    #
628
    #   Insert markers(++) into @aruments to mark when to process collected data
629
    #   Insert before each PLATFORM and at the end of the list
630
    #   platform specifier or the end of the list. Scan the arguments
631
    #
632
    @arguments = ExpandPlatforms( @arguments );
633
    my @new_args;
634
    foreach  ( @arguments )
635
    {
636
        push (@new_args, '++') unless ( m/^--/ );
637
        push (@new_args, $_ );
638
    }
639
    push (@new_args, '++');
640
    shift @new_args if $new_args[0] eq '++';
641
 
5115 dpurdie 642
    my @targs = @alias;
227 dpurdie 643
    my $target;
644
    my @tuses = @uses;
645
    foreach my $arg ( @new_args )
646
    {
647
        #
648
        #   Collect per-platform arguments
649
        #
650
        if ( $arg =~ /^--Uses=(.*)/ ) {
651
            UniquePush (\@tuses, $1);
652
            next;
653
 
654
        } elsif ( $arg =~ /^--/ ) {
655
            push @targs, $arg;
656
            next;
657
        }
658
 
659
        #
660
        #   Collect target(platform) name
661
        #
662
        unless ( $arg eq '++' )
663
        {
664
            $target = $arg;
665
            Error( "BuildProduct() cannot create a product based on a GENERIC platform" )
4551 dpurdie 666
                if ( PlatformConfig::checkBuildAvailability($target) == 2);
227 dpurdie 667
            next;
668
        }
669
 
670
        #
671
        #   Infer a BuildPlatform
672
        #   Do not provide a platform name. This will be created later when the
673
        #   full name is known - or can be calculated.
674
        #
675
        CreateBuildPlatformEntry('BuildProduct', $notdefault, $product, $target, \@tuses, \@targs );
676
 
5115 dpurdie 677
        @targs = @alias;
227 dpurdie 678
        @tuses = @uses;
679
        $target = undef;
680
    }
681
}
682
 
683
#-------------------------------------------------------------------------------
684
# Function        : CreateBuildPlatformEntry
685
#
686
# Description     : Internal routine to create the Build Entry
687
#                   Single point to create a platform, whatever one of those is
688
#
689
# Inputs          : $fname                  - Name of invoking directive
690
#                   $notdefault             - True if the platform is not to be added to the
691
#                                             list of default platforms
692
#                   $product                - Optional product name
693
#                   $target                 - Target platform name
694
#                   $pUses                  - Ref to an array of 'Uses'
695
#                   $pArgs                  - Ref to an array of platform arguments
696
#
697
# Returns         :
698
#
699
 
700
sub CreateBuildPlatformEntry
701
{
702
    my ($fname, $notdefault, $product, $target, $pUses, $pArgs ) = @_;
703
    my %buildentry;
704
    my $platform;
705
 
706
    #
707
    #   Create a basic BUILDINFO entry
708
    #
709
    $buildentry{FNAME} = $fname;
710
    $buildentry{NOT_DEFAULT} = $notdefault;
711
    $buildentry{PRODUCT} = $product;
712
    $buildentry{TARGET} = $target;
713
    $buildentry{BASE} = $target;
714
    $buildentry{USES} = [ @$pUses ] if $pUses;
363 dpurdie 715
    foreach ( @$pArgs )
716
    {
717
        if ( m~^--Alias=(.+)~ ) {
718
            push @{$buildentry{USERALIAS}}, split(',',$1);
719
        }
720
        else{
721
            push @{$buildentry{ARGS}}, $_;
722
        }
723
    }
227 dpurdie 724
 
4728 dpurdie 725
    #   Detect reserved words being misused as a platform name
726
    #   At the moment, the value of NATIVE is calculate towards the end of the
727
    #   build process so that it can be limited to platfroms that 
728
    #   are present.
729
    Error('Invalid use of the platform alias NATIVE','The NATIVE alias cannot be used to define build platforms')
730
        if (uc($target) eq 'NATIVE');
731
 
227 dpurdie 732
    #
733
    #   Allow per-platform processing to be alter the basic information
734
    #   Special processing may be perform to extend the information
735
    #   Allows special processing to be enabled on a per-target basis
736
    #
737
    #   There are three forms of processing that have been allowed for:
738
    #       1) None:        There is not platform specific extension
739
    #       2) Basic:       The extension will add or extend build information
740
    #       3) Advanced:    The extension will generate additional build information
741
    #                       structures.
742
    #
743
 
744
    #
745
    #   Locate the optional PLATFORM configuration file
746
    #   If it does exist then it can alter build-time information
747
    #
748
    if ( my $build_cfg = Require( "$::GBE_CONFIG/PLATFORM", "$target.cfg"  ) )
749
    {
750
        Verbose ("Processing(new) Platform Configuration file: $build_cfg");
751
 
297 dpurdie 752
        #
303 dpurdie 753
        #   Create package name with an uppercase target
754
        #   Target should be UC, but under windows its not detected
755
        #   at this time
756
        #
757
        my $package_name = uc($target) . '_Build';
758
 
759
        #
4551 dpurdie 760
        #   Ensure that the CFG is correctly formed
297 dpurdie 761
        #       Perhaps the package that it implements was misnamed
762
        #
303 dpurdie 763
        Error ("INTERNAL: $target.cfg does not satisfy API " )
297 dpurdie 764
            unless ( $package_name->can('new_platform') || $package_name->can('add_platform') );
765
 
227 dpurdie 766
        if ( $package_name->can('new_platform') )
767
        {
768
            Verbose ("Processing(new) Platform Configuration: $package_name");
769
            $package_name->new_platform( \%buildentry );
770
        }
771
        else
772
        {
773
            Debug ("Processing(new) Platform Configuration: $package_name. 'new_platform' function not found");
774
        }
775
    }
776
 
777
    #
778
    #   Add the basic entry into the build system, unless its been
779
    #   flagged as a TEMPLATE
780
    #
781
    AddBuildPlatformEntry (\%buildentry )
782
        unless ( $buildentry{TEMPLATE} );
783
}
784
 
785
 
786
#-------------------------------------------------------------------------------
787
# Function        : AddBuildPlatformEntry
788
#
789
# Description     : Internal routine to add a Build Entry into the build system
790
#                   This function MAY be called from the build extensions
791
#
792
#                   NOTES:
793
#                   No processing of the info structure is performed. This MUST
794
#                   have been done before now.
795
#
796
#                   Additional information may be added to the structure.
797
#
798
#
799
# Inputs          : $pInfo              - Reference to a BuildInfo structure
800
#
801
# Returns         : Nothing
802
#
803
sub AddBuildPlatformEntry
804
{
805
    my ($pInfo) = @_;
806
    my $fname = $pInfo->{FNAME};
807
 
808
    #
809
    #   Locate the optional PLATFORM configuration file
810
    #   If it does exist then it can extend build-time information
811
    #
812
    my $target = $pInfo->{TARGET};
241 dpurdie 813
 
279 dpurdie 814
    #
815
    #   Yukky Kludge
816
    #   JATS has a mechanism whereby packages can create new platforms
817
    #   Luckily this has only been done for LMOS - don't every do it again
818
    #   One problem is that we can't validate the target name at this point
819
    #   in time: as the packages are loaded much later.
820
    #
821
    #   Kludge. Assume that a leading LMOS_ can be removed when determing
822
    #           validity of the target platform.
823
    #
824
    my $base_target = $target;
825
    $base_target =~ s~^LMOS_~~;
241 dpurdie 826
 
279 dpurdie 827
    #
4551 dpurdie 828
    #   Detect GENERIC targets
829
    #       The Build file is only allowed to have one that can be built on any one machine
830
    #
831
    my $buildAvailability = PlatformConfig::checkBuildAvailability( $base_target );
832
    if ($buildAvailability == 2 )
833
    {
834
        UniquePush (\@GENERIC_TARGETS, $target );
835
        $pInfo->{IS_GENERIC} = 1;
836
    }
837
 
838
    #
279 dpurdie 839
    #   Ensure target is known to JATS
840
    #   Remove unknown targets from the build. Create a list of unknown
841
    #   targets and report them later.
842
    #
843
    #   If there are signs that the target has been processed, then it may be
844
    #   an alias that has not been expanded.
845
    #
846
    #   One result will be that alias platforms, such as DEVLINUX, that don't
847
    #   expand on WIN32 will be shown as DEVLINUX and not its components.
848
    #
4551 dpurdie 849
    unless ( $pInfo->{NOT_AVAILABLE} || exists $BUILDINFO{$target} || $pInfo->{IS_GENERIC} )
227 dpurdie 850
    {
279 dpurdie 851
        unless ( Exists( "$::GBE_CONFIG/PLATFORM", $base_target  ) )
852
        {
4551 dpurdie 853
            UniquePush (\@BUILD_BADNAME, $target ) 
854
                unless PlatformConfig::checkKnownSpecial($target);
279 dpurdie 855
            $pInfo->{NOT_AVAILABLE} = 1;
856
        }
857
    }
858
 
859
    #
4551 dpurdie 860
    #   Mark as NOT_AVAILABLE platforms that are not available on this machine
279 dpurdie 861
    #
862
    unless ($pInfo->{NOT_AVAILABLE} )
863
    {
864
        $pInfo->{NOT_AVAILABLE} = 1
4551 dpurdie 865
            if ($buildAvailability == 0 )
279 dpurdie 866
    }
867
 
868
    unless ($pInfo->{NOT_AVAILABLE} )
869
    {
4551 dpurdie 870
        my $target_cfg = $pInfo->{TARGET_CFG} || $target;
317 dpurdie 871
        if ( my $build_cfg = Require( "$::GBE_CONFIG/PLATFORM", "${target_cfg}.cfg"  ) )
227 dpurdie 872
        {
873
            Verbose ("Processing(add) Platform Configuration file: $build_cfg");
317 dpurdie 874
            my $package_name = "${target_cfg}_Build";
227 dpurdie 875
 
876
            if ( $package_name->can('add_platform') )
877
            {
878
                Verbose ("Processing(add) Platform Configuration: $package_name");
879
                $package_name->add_platform( $pInfo );
880
            }
881
            else
882
            {
883
                Debug ("Processing(add) Platform Configuration: $package_name. 'add_platform' function not found");
884
            }
885
        }
886
    }
887
 
888
    #
889
    #   If a product name has been provided then the platform is a product
890
    #   and will need additional processing
891
    #
892
    if ( $pInfo->{PRODUCT} )
893
    {
894
        #
895
        #   Create the platform name. Derived from the product and the target
896
        #
897
        $pInfo->{PLATFORM} = $pInfo->{PRODUCT} . '_' . $pInfo->{TARGET};
898
 
899
        #
900
        #   Remember the product name
901
        #
902
        $BUILDPRODUCT{ $pInfo->{PRODUCT} } = 1;
903
 
904
        #
905
        #   Add platform name to the alias explansion being created
906
        #   Allows the user to reference the entire FAMILY of platforms
907
        #
908
        HashJoin( \%BUILDALIAS, ' ', $pInfo->{PRODUCT}, $pInfo->{PLATFORM} );
909
 
910
        #
911
        #   Add arguments to the 'alias' based on the product
912
        #   Ensure they don't make it any further
913
        #
914
        HashJoin( \%BUILDALIAS, ' ', $pInfo->{PRODUCT}, @{$pInfo->{ARGS}} ) if ( $pInfo->{ARGS}  );
915
        $pInfo->{ARGS} = undef;
916
 
917
        #
918
        #   Create an element to assist in creating %ScmBuildProducts
919
        #
920
        $pInfo->{ISPRODUCT} = 1;
921
        $BUILDPRODUCT_PARTS{$pInfo->{PLATFORM}} = "$pInfo->{PRODUCT},$pInfo->{TARGET}";
922
    }
923
    else
924
    {
925
        $pInfo->{PRODUCT} = $pInfo->{TARGET};
926
        $pInfo->{PLATFORM} = $pInfo->{TARGET};
927
    }
928
 
929
    #---------------------------------------------------------------------------
930
    #   All the hard work has been done
931
    #   We now know the platforms full name
932
    #
933
    #   Ensure that the target platform has not been been specified
934
    #   Perhaps this should be an error
935
    #
936
    my $platform = $pInfo->{PLATFORM};
937
 
5109 dpurdie 938
    if ( defined ( $BUILDINFO{$platform}) && ! $Clobber)
227 dpurdie 939
    {
5410 dpurdie 940
        abtWarning("$fname() duplicate platform '$platform'");
941
        ErrorDoExit();
5429 dpurdie 942
        return;
227 dpurdie 943
    }
944
 
945
    #
946
    #   Add platform (tag) to various lists
947
    #
948
    UniquePush( \@BUILDPLATFORMS, $platform );
949
    UniquePush( \@DEFBUILDPLATFORMS, $platform ) unless ( $pInfo->{NOT_DEFAULT} );
950
 
951
    #
952
    #   Create a simple alias if requested
953
    #   Used if a platform creates multiple entires
954
    #
955
    if ( $pInfo->{ALIAS} )
956
    {
317 dpurdie 957
        HashJoin( \%BUILDALIAS_DELAY, ' ', $_, $platform )
958
            foreach ( ArrayList($pInfo->{ALIAS}) );
227 dpurdie 959
    }
960
 
363 dpurdie 961
    if ( $pInfo->{USERALIAS} )
962
    {
963
        HashJoin( \%BUILDALIAS_DELAY, ' ', $_, $platform )
964
            foreach ( ArrayList($pInfo->{USERALIAS}) );
965
    }
966
 
227 dpurdie 967
    #
968
    #   Create a HARDWARE type alias if requested
969
    #   ie: SOLARIS_SPARC or SOLARIS_X86
970
    #
971
    if ( $pInfo->{HARDWARE} )
972
    {
973
        HashJoin( \%BUILDALIAS_DELAY, ' ',  $pInfo->{BASE} . '_' . $pInfo->{HARDWARE}, $platform );
974
    }
975
 
976
    #
977
    #   Create the 'parts' of the platform. This is a list of unique
978
    #   bits to search. It will consist of:
979
    #       [0]     - platform
980
    #       [1]     - product
981
    #       ...     - Uses bits ...
982
    #       [last]  - target
983
    #
984
    my @parts;
985
 
379 dpurdie 986
    if ( $pInfo->{USES_FIRST} )
987
    {
988
        UniquePush (\@parts, @{$pInfo->{USES_FIRST}} );
989
    }
990
 
991
    UniquePush (\@parts, $platform);
992
 
227 dpurdie 993
    #
994
    #   Include all the product extensions
995
    #
996
    if ( $pInfo->{ISPRODUCT}  )
997
    {
998
        UniquePush (\@parts, map {+ "$pInfo->{PRODUCT}_${_}" } @{$pInfo->{USES}});
999
        UniquePush (\@parts, map {+ "$pInfo->{PRODUCT}_${_}" } @{$pInfo->{ALSO_USES}});
1000
        UniquePush (\@parts, $pInfo->{PRODUCT} );
1001
    }
1002
 
1003
    #
1004
    #   Add in non-product expanded parts
1005
    #
1006
    UniquePush (\@parts, @{$pInfo->{EXTRA_USES}});
1007
 
1008
    #
1009
    #   Create a structure to assist in search path resolution
1010
    #   The order is important. It sets the include search order for include
1011
    #   files and libraries
1012
    #   If A uses B then search in A_B, A, B
1013
    #       ie: GAK uses MOS68K Search stuff in GAK_MOS68K, GAK, MOS68K
1014
    #
1015
    #       Usage:  OBFTP uses TP5 on MOSCF(target)       (BuildProduct)
1016
    #       Expansion: OBFTP, TP5_MOSCF, TP5
1017
    #
1018
    #       Usage: VS2003(target) also uses WIN32(uses)     (BuildPlatform)
1019
    #       Expansion: VS2003, VS2003_WIN32, WIN32
1020
    #
1021
    if ( $pInfo->{ISPRODUCT}  )
1022
    {
1023
        UniquePush (\@parts, map {+ "${_}_$pInfo->{TARGET}", $_, $pInfo->{TARGET}} @{$pInfo->{USES}});
1024
        UniquePush (\@parts, map {+ "${_}_$pInfo->{TARGET}", $_, $pInfo->{TARGET}} @{$pInfo->{ALSO_USES}});
1025
    }
1026
    else
1027
    {
1028
        UniquePush (\@parts, map {+ "$pInfo->{TARGET}_${_}", $pInfo->{TARGET}, $_} @{$pInfo->{USES}});
1029
        UniquePush (\@parts, map {+ "$pInfo->{TARGET}_${_}", $pInfo->{TARGET}, $_} @{$pInfo->{ALSO_USES}});
1030
    }
1031
 
1032
    #
1033
    #   Finally - the target
1034
    #
1035
    UniquePush (\@parts, $pInfo->{TARGET} );
1036
 
1037
    #
1038
    #   Save the PARTS
1039
    #   Also saved as BUILDPLATFORM_PARTS for interface with older versions
1040
    #   of the deployments scripts.
1041
    #
1042
    $pInfo->{PARTS} = \@parts;
1043
 
1044
    #
1045
    #   Add any arguments to the platforms argument list
1046
    #
1047
    PlatformArgument( $platform, @{$pInfo->{ARGS}} ) if ( $pInfo->{ARGS} );
1048
 
1049
    #
1050
    #   Clean up and save
1051
    #
1052
    delete $pInfo->{TEMPLATE};
1053
    delete $pInfo->{FNAME};
1054
    $BUILDINFO{$platform} = $pInfo;
1055
#    DebugDumpData("BUILDINFO", \%BUILDINFO );
1056
}
1057
 
1058
 
1059
sub BuildArgument
1060
{
1061
    my( $platform, @arguments ) = @_;
1062
    my( @platforms );
1063
 
1064
    Debug( "BuildArgument($platform, @arguments)" );
1065
 
1066
    Error( "BuildArgument must appear before BuildName()..." )
1067
        if ( $BUILDNAME ne "" );
1068
 
1069
    #
1070
    #   Allow a wildcard to apply a single argument to all platforms
1071
    #   Should only be used AFTER all the platforms have been specified
1072
    #
1073
    if ( $platform eq '*' )
1074
    {
1075
        @platforms = @BUILDPLATFORMS;          # Simple Wildcard
1076
    }
1077
    else
1078
    {
1079
        @platforms = ExpandPlatforms( $platform );  # aliasing
1080
    }
1081
 
283 dpurdie 1082
    foreach my $platform ( @platforms )
227 dpurdie 1083
    {
1084
        next if ( $platform =~ /^--/ );         # argument, ignore
1085
 
1086
        PlatformArgument( $platform, @arguments );
1087
    }
1088
}
1089
 
1090
 
1091
sub BuildPlatforms
1092
{
1093
    my( @arguments ) = @_;
1094
    my $fname = "BuildPlatforms";
1095
 
1096
    Debug( "BuildPlatforms(@arguments)" );
1097
 
1098
    Error( "BuildPlatforms must appear before BuildName()..." )
1099
        if ( $BUILDNAME ne "" );
1100
 
1101
    #
1102
    #   Expand the user specified platforms to allow the use of BuildAlias
1103
    #   The (bad) side effect of this is that platform options get reorganised
1104
    #       PLATFORM,--Uses=ANOTHER  ==> PLATFORM --Uses=ANOTHER
1105
    #
1106
    #   Insert markers(++) into @aruments to mark when to process collected data
1107
    #   Insert before each PLATFORM and at the end of the list
1108
    #   platform specifier or the end of the list. Scan the arguments
1109
    #
1110
    @arguments = ExpandPlatforms( @arguments );
1111
    my @new_args;
1112
    foreach  ( @arguments )
1113
    {
1114
        push (@new_args, '++') unless ( m/^--/ );
1115
        push (@new_args, $_ );
1116
    }
1117
    push (@new_args, '++');
1118
    shift @new_args if $new_args[0] eq '++';
1119
 
1120
 
1121
    my $platform  = "";                         # current platform
1122
    my $notdefault  = 0;
1123
    my @uses = ();
1124
    my @pargs = ();
1125
 
1126
    foreach my $arg ( @new_args )
1127
    {
1128
        #
1129
        #   Extract known options
1130
        #   Unknown options bind to the current platform
1131
        #
1132
        if ( $arg =~ /^--/ ) {
1133
            if ( $arg =~ /^--NotDefault$/ ) {
1134
                $notdefault = 1;
1135
 
1136
            } elsif ( $arg =~/^--Uses=(.*)/ ) {
1137
                UniquePush (\@uses, $1);
1138
 
1139
            } elsif ( $arg =~/^--FunctionName=(.*)/ ) {
1140
                $fname = $1;
1141
 
1142
            } else {
1143
                push @pargs, $arg;
1144
            }
1145
            next;
1146
        }
1147
 
1148
        #
1149
        #   New platform. Save name for later. Collect arguments first
1150
        #
1151
        unless ( $arg eq '++' )
1152
        {
1153
            $platform = $arg;
1154
 
1155
            Error( "$fname() missing platform specification" )
1156
                unless ( $platform );
1157
 
1158
            Error( "$fname() product '$platform' contains invalid characters" )
1159
                unless ( $platform eq quotemeta( $platform ) );
1160
 
1161
            next;
1162
        }
1163
 
1164
        #
1165
        #   Create new platform
1166
        #   Have collected name and arguments
1167
        #
1168
        CreateBuildPlatformEntry($fname, $notdefault, undef, $platform, \@uses, \@pargs  );
1169
 
1170
        #
1171
        #   Reset collection variables for next platform
1172
        #
1173
        $platform = "";
1174
        $notdefault  = 0;
1175
        @uses = ();
1176
        @pargs = ();
1177
    }
1178
}
1179
 
1180
 
1181
#   PlatformArgument ---
1182
#       Append an argument list to the specified platform argument list.
1183
#       Internal use only
1184
#..
1185
 
1186
sub PlatformArgument
1187
{
1188
    my( $platform, @arguments ) = @_;
1189
 
1190
    Debug( "  PlatformArguments($platform, @arguments)" );
1191
 
1192
    HashJoin( \%BUILDPLATFORMARGS, $;, $platform, @arguments )
1193
        if ( $platform );
1194
}
1195
 
279 dpurdie 1196
#-------------------------------------------------------------------------------
5679 dpurdie 1197
# Function        : BuildExclude 
1198
#
1199
# Description     : Allow specific platforms to be excluded from the Build
1200
#                   Intended use:
1201
#                       Allow the use if a platform alias, but not all elements of it
1202
#                       ie: Use DEVLINUX, but not ARM9TDMI as we no longer support it 
1203
#                           in this version.
1204
#                   Multiple BuildExclude directives are allowed
1205
#                   Order or location is not important        
1206
#
1207
# Inputs          : Platforms names and options
1208
#                   Format:
1209
#                       --PLATFORM=xxxxx    (Marginal use)
1210
#                       --PRODUCT=yyyy      (Not very useful)
1211
#                       --TARGET=zzzz       (Default)
1212
#                       zzzz                (Same as --TARGET=ZZZZ)
1213
#                       
1214
#
1215
# Returns         : Nothing 
1216
#
1217
sub BuildExclude
1218
{
1219
    my( @arguments ) = @_;
1220
    Debug( "BuildExclude(@arguments)" );
1221
 
1222
    Error( "BuildExclude must appear before BuildName()..." )
1223
        if ( $BUILDNAME ne "" );
1224
 
1225
    #
1226
    #   Simply save the arguments for later
1227
    #   Allow multiple specs in the one definition
1228
    #
1229
    foreach ( @arguments)
1230
    {
1231
        UniquePush (\@BUILDEXCLUDE, split(/\s*,\s*/,$_));
1232
    }
1233
}
1234
 
1235
#-------------------------------------------------------------------------------
279 dpurdie 1236
# Function        : BuildName
1237
#
1238
# Description     : Defines the package name and version
1239
#
1240
# Inputs          : build arguments
1241
#                   Various formats are allowed for backward compatability
1242
#                   Must support a number of different formats
1243
#                       "name nn.nn.nn prj"
1244
#                       "name nn.nn.nn.prj"
1245
#
1246
#                       "name nn.nn.nn prj", "nn.nn.nn"
1247
#                       "name nn.nn.nn.prj", "nn.nn.nn"
1248
#
1249
#                       "name", "nn.nn.nn.prj"
1250
#
1251
#                       "name", "nn.nn.nn", "prj", --RelaxedVersion
1252
#
1253
# Returns         : Nothing
1254
#
227 dpurdie 1255
sub BuildName
1256
{
1257
    my( @arguments ) = @_;
1258
    my $relaxed_version_name = 0;
1259
    my @args;
1260
 
1261
    Debug( "BuildName(@arguments)" );
1262
 
315 dpurdie 1263
    Error( "Platform(s) not defined.",
227 dpurdie 1264
            "BuildAlias, BuildProduct and BuildPlatform directives must be defined prior to BuildName()." )
1265
        unless( scalar @BUILDPLATFORMS );
1266
 
1267
#.. Parse arguments
1268
#.
1269
    my $build_info = parseBuildName( @arguments );
1270
 
1271
    $BUILDNAME_PACKAGE = $build_info->{BUILDNAME_PACKAGE};
1272
    $BUILDNAME_VERSION = $build_info->{BUILDNAME_VERSION};
1273
    $BUILDNAME_PROJECT = $build_info->{BUILDNAME_PROJECT};
359 dpurdie 1274
    $BUILDNAME_SUFFIX  = $BUILDNAME_PROJECT ? '.' . $BUILDNAME_PROJECT : '';
227 dpurdie 1275
 
1276
    $BUILDNAME         = $build_info->{BUILDNAME};
1277
    $BUILDVERSION      = $build_info->{BUILDVERSION};
1278
 
1279
    $DEPLOY_PATCH      = $build_info->{DEPLOY_PATCH} || 0;
1280
 
1281
    #
1282
    #   Clobber processing done after values have been accumulated
1283
    #   as they may be used later
1284
    #
1285
    return if ( $Clobber );
4003 dpurdie 1286
    ToolsetFile('build.log');
1287
    ToolsetFile('ChangeLog', 'ChangeLog.bak') if ( $ScmHost eq "Unix" );
1288
 
359 dpurdie 1289
    #
1290
    #   Determine type of sandbox
1291
    #
1292
    $sandbox_exact = ( -f $::GBE_DPKG_SBOX . '/.exact' )
1293
        if ( $::GBE_DPKG_SBOX );
1294
 
227 dpurdie 1295
#.. Create the ChangeLog
1296
#
1297
    if ( -d "CVS" )                             # CVS support subdir
1298
    {
1299
        System( "$::GBE_PERL $::GBE_TOOLS/cvs2cl.pl --tags --branches --revisions --day-of-week" )
1300
            if ( $Nolog == 0 && $ScmHost eq "Unix" );
1301
    }
1302
 
1303
 
1304
#.. Create build.log summary information
1305
#
261 dpurdie 1306
    my ($sep) = "\n".(" " x 11) . ". ";
227 dpurdie 1307
 
261 dpurdie 1308
    Log( "\nBuild configuration (version $::GBE_VERSION)" );
1309
    Log( "Name ....... $BUILDNAME ($ScmHost)" );
1310
    Log( "Version .... $BUILDNAME_VERSION" );
1311
    Log( "DeployPatch. $DEPLOY_PATCH" ) if ($DEPLOY_PATCH);
1312
    Log( "Project .... $BUILDNAME_PROJECT" )if ($BUILDNAME_PROJECT);
1313
    Log( "Project .... ****** Specifically supressed ******" )unless ($BUILDNAME_PROJECT);
1314
    Log( "DateTime ... $::CurrentTime" );
1315
    Log( "AutoBuild... Enabled:$::GBE_ABT" ) if defined($::GBE_ABT) ;
359 dpurdie 1316
    Log( "Build dir... $Cwd" ) if defined($::GBE_ABT) || $::GBE_DPKG_SBOX;
4161 dpurdie 1317
    Log( "Build Mach.. $::GBE_HOSTNAME" ) if defined($::GBE_ABT);
227 dpurdie 1318
 
359 dpurdie 1319
    Log( "PERL ....... $::GBE_PERL" );
261 dpurdie 1320
    Log( "BIN  ....... $::GBE_BIN" );
1321
    Log( "TOOLS ...... $::GBE_TOOLS" );
1322
    Log( "CONFIG ..... $::GBE_CONFIG" );
1323
    Log( "MACHTYPE ... $::GBE_MACHTYPE" );
227 dpurdie 1324
 
261 dpurdie 1325
    Log( "PLATFORM ... " . PrintList([split(' ', $::GBE_PLATFORM)], $sep) )    if defined ($::GBE_PLATFORM);
5679 dpurdie 1326
    Log( "EXCLUDE .... " . PrintList([@BUILDEXCLUDE], $sep) )    if defined (@BUILDEXCLUDE);
261 dpurdie 1327
    Log( "BUILDFILTER. " . PrintList([split(' ', $::GBE_BUILDFILTER)], $sep) ) if defined ($::GBE_BUILDFILTER);
227 dpurdie 1328
 
261 dpurdie 1329
    Log( "DPKG_STORE.. $::GBE_DPKG_STORE" );
1330
    Log( "DPKG ....... $::GBE_DPKG" );
4688 dpurdie 1331
    Log( "DPKG_REPLI . $::GBE_DPKG_REPLICA" );
261 dpurdie 1332
    Log( "DPKG_CACHE . $::GBE_DPKG_CACHE" );
1333
    Log( "DPKG_LOCAL . $::GBE_DPKG_LOCAL" );
1334
    Log( "DPKG_SBOX .. $::GBE_DPKG_SBOX" );
359 dpurdie 1335
    Log( "Sandbox .... " . ($sandbox_exact ? "Exact" : "Development") );
3559 dpurdie 1336
    Log( "LocalFilter. $::GBE_SANDBOX/buildfilter") if ( $::GBE_SANDBOX && -f $::GBE_SANDBOX . '/buildfilter' );
227 dpurdie 1337
 
261 dpurdie 1338
    Log( "Platforms .. " . PrintPlatforms(\@BUILDPLATFORMS, $sep) );
227 dpurdie 1339
 
1340
    #
241 dpurdie 1341
    #   Generate a list of platforms that are completely unknown to JATS
4003 dpurdie 1342
    #   May be the result of a user typo or a guess
241 dpurdie 1343
    #
1344
    if ( @BUILD_BADNAME )
1345
    {
281 dpurdie 1346
        Log( "Unknown Pl . " . PrintPlatforms(\@BUILD_BADNAME, $sep) );
4551 dpurdie 1347
        Warning ("The following platform names are not known to JATS", "@BUILD_BADNAME");
241 dpurdie 1348
    }
4551 dpurdie 1349
 
241 dpurdie 1350
    #
4551 dpurdie 1351
    #   Detect multiple GENERIC targets
1352
    #       Only one such target can be processed on any one machine
1353
    #
1354
    if ($#GENERIC_TARGETS > 0)
1355
    {
1356
        Error ("Multiple GENERIC targets detected", PrintPlatforms(\@GENERIC_TARGETS, $sep));
1357
    }
1358
    if ($#GENERIC_TARGETS >= 0 )
1359
    {
1360
        $All = 1;
1361
    }
1362
 
1363
    #
227 dpurdie 1364
    #   Generate a list of active platforms
1365
    #   Ensure that there are some active platforms
1366
    #
1367
    GeneratePlatformList();
4551 dpurdie 1368
 
1369
    #
1370
    #   Detect a mix of Generic and non Generic targets
1371
    #       Cannot mix generic and non-generic targets
1372
    #
1373
    if ($#GENERIC_TARGETS >= 0 && $#BUILD_ACTIVEPLATFORMS >= 0)
1374
    {
1375
        if ($#BUILD_ACTIVEPLATFORMS != $#GENERIC_TARGETS )
1376
        {
1377
            Verbose("Active:", @BUILD_ACTIVEPLATFORMS);
1378
            Verbose("Generic:", @GENERIC_TARGETS);
1379
            Error("Cannot mix GENERIC and non-GENERIC targets in the one build");
1380
        }
1381
    }
1382
 
4778 dpurdie 1383
    #
1384
    #   Build System Generic Saniy Test
1385
    #       If Generic   then MUST be a GENERIC build
1386
    #       If NoGeneric then MUST not be a GENERIC build
1387
    #
1388
    if (defined $GenericBuild)
1389
    {
1390
        if ( scalar(@GENERIC_TARGETS) ne $GenericBuild)
1391
        {
1392
            Error("Generic build inconsistency",
1393
                  "Release Manager entry indicates: $GenericBuild",
1394
                  "Build File indicates: " . scalar(@GENERIC_TARGETS)
1395
                  );
1396
        }
1397
    }
1398
 
4003 dpurdie 1399
    unless( @BUILD_ACTIVEPLATFORMS )
1400
    {
5109 dpurdie 1401
        my $msg = 'GBE_BUILDFILTER prevents any targets being built';
4003 dpurdie 1402
        if (defined($::GBE_ABT)) {
227 dpurdie 1403
 
4003 dpurdie 1404
            # Build filter on this machine prevents the package building
1405
            # On a Build System this is not an error
1406
            #   Create a dummy platform called NOBUILD
1407
            #   Do not populate the interface directory with package data
1408
            #   Flag for jmake to do very little
1409
            #
1410
            CreateBuildPlatformEntry('Internal', 0, undef, 'NOBUILD');
1411
            $IgnorePkgs = 1;
1412
            $NoBuild = 1;
5109 dpurdie 1413
            Log( "Build for .. ". PrintPlatforms(['NOBUILD - ' . $msg], $sep));
4003 dpurdie 1414
 
1415
        } else {
5109 dpurdie 1416
            Error( $msg );
4003 dpurdie 1417
        }
1418
    }
1419
    else
1420
    {
1421
        Log( "Build for .. ". PrintPlatforms(\@BUILD_ACTIVEPLATFORMS, $sep));
1422
    }
1423
 
227 dpurdie 1424
    #
1425
    #   Generate an error if nothing can be done because the GBE_PLATFORM
1426
    #   masks any useful operation.
1427
    #
1428
    if ( $::GBE_PLATFORM )
1429
    {
1430
        my @MAKE_PLATFORMS;
1431
        my %active_platforms;
1432
 
239 dpurdie 1433
        #
1434
        #   Create a hash of active platforms based on the array of
1435
        #   active platforms to simplify testing
1436
        #
1437
        $active_platforms{$_} = 1 foreach ( @BUILD_ACTIVEPLATFORMS  );
227 dpurdie 1438
 
4551 dpurdie 1439
        unless ( $#GENERIC_TARGETS >= 0 )
227 dpurdie 1440
        {
239 dpurdie 1441
            foreach  ( split( ' ', $::GBE_PLATFORM) )
1442
            {
1443
                push @MAKE_PLATFORMS, $_
1444
                    if ( $active_platforms{$_} );
1445
            }
227 dpurdie 1446
 
239 dpurdie 1447
            Error ("The GBE_PLATFORM filter prevents any targets being made",
1448
                   "GBE_PLATFORM: $::GBE_PLATFORM" ) unless ( @MAKE_PLATFORMS );
227 dpurdie 1449
 
261 dpurdie 1450
            Log( "Make for ... ". PrintPlatforms(\@MAKE_PLATFORMS, $sep));
239 dpurdie 1451
        }
227 dpurdie 1452
 
1453
    }
1454
 
1455
    return 1;
1456
}
1457
 
1458
 
1459
sub BuildPreviousVersion
1460
{
1461
    my( $version ) = shift;
1462
 
1463
    $BUILDPREVIOUSVERSION = $version;
261 dpurdie 1464
    Log( "Previous Version ... $BUILDPREVIOUSVERSION" );
227 dpurdie 1465
 
1466
    return 1;
1467
}
1468
 
1469
 
1470
sub BuildInterface
1471
{
1472
    my( $ifdirname ) = @_;
1473
 
1474
 
1475
    #
1476
    #   Clobber the directory - at the end.
1477
    #
1478
    if ( $Clobber )
1479
    {
1480
        #
1481
        #   If this Interface directory contains the Dpackage.cfg file
1482
        #   then JATS has created DPACKAGE and it needs to be clobbered
1483
        #   Flag that it needs to be done later - when we know where it is
1484
        #
1485
        $DeleteDPACKAGE = 1 if ( -f "$ifdirname/Dpackage.cfg" );
1486
 
1487
        push @CLOBBERDIRS, $ifdirname;
1488
        return;
1489
    }
1490
 
1491
    #
1492
    #   In AutoBuildTool mode the entire interface directory
1493
    #   will be deleted. This allows the build to be retried
1494
    #
1495
    if (  defined($::GBE_ABT) )   # clobber mode ?
1496
    {
361 dpurdie 1497
        if ( -d $ifdirname )
227 dpurdie 1498
        {
361 dpurdie 1499
                RmDirTree( $ifdirname );
227 dpurdie 1500
        }
1501
    }
1502
 
1503
    if ( $ifdirname eq "local" ) {
341 dpurdie 1504
        mkpath ( "$ifdirname/inc" );
227 dpurdie 1505
        $BUILDLOCAL = "local";
1506
 
1507
    } else {
341 dpurdie 1508
        mkpath ( "$ifdirname/include" );
227 dpurdie 1509
        $BUILDINTERFACE = $ifdirname;
1510
        $::ScmInterface = $ifdirname;
1511
    }
341 dpurdie 1512
    mkpath ( "$ifdirname/bin" );
1513
    mkpath ( "$ifdirname/lib" );
227 dpurdie 1514
 
261 dpurdie 1515
    Log( "Interface .. $ifdirname" );
227 dpurdie 1516
    return 1;
1517
}
1518
 
1519
 
1520
sub BuildDirTree
1521
{
1522
    my( $dirfile, $dirhead ) = @_;
1523
    my( $dirname, $c );
1524
 
1525
    $dirhead = '.'
1526
        unless defined( $dirhead );
1527
 
1528
    if ( $Clobber )                             # clobber mode ?
1529
    {
1530
        push @CLOBBERDIRS, $dirhead unless $dirhead eq '.';
1531
        return;
1532
    }
1533
 
1534
    #
1535
    #   Allow for an empty "dirfile". This will allow a directory to be created
1536
    #   without the overhead of the file
1537
    #
1538
    if ( ! $dirfile )
1539
    {
261 dpurdie 1540
        Log( "DirTree .... $dirhead" );
341 dpurdie 1541
        mkpath ( $dirhead );
227 dpurdie 1542
    }
1543
    else
1544
    {
261 dpurdie 1545
        Log( "DirTree .... $dirfile within $dirhead" );
341 dpurdie 1546
        mkpath ( $dirhead );
1547
 
283 dpurdie 1548
        open( DIRFILE, '<' ,$dirfile ) ||
227 dpurdie 1549
            Error( "cannot open '$dirfile'" );
1550
 
1551
        while( $dirname = <DIRFILE> )
1552
        {
1553
            chop $dirname;
1554
            $dirname =~ s/#.*//;
1555
            $c = $dirname =~ s/\s*(\S+).*/$1/g;
1556
 
1557
            next unless ( $c == 1 );
1558
 
1559
            if ( ! -d "$dirhead/$dirname" )
1560
            {
261 dpurdie 1561
                Log( "Dir ........ $dirhead/$dirname" );
341 dpurdie 1562
                mkpath ( "$dirhead/$dirname" );
227 dpurdie 1563
            }
1564
        }
1565
 
1566
        close( DIRFILE );
1567
    }
1568
    $BUILDDIRTREE = $dirhead;
1569
}
1570
 
1571
#-------------------------------------------------------------------------------
1572
# Function        : IncludePkg
1573
#
1574
# Description     : Examine a fully specified package directory for a file
1575
#                   that will specify packages to be included. This allows
1576
#                   a package to be simply a package of other packages
1577
#
1578
#                   Internal function. Not to be used by users
1579
#
1580
# Inputs          : Name of the package
1581
#                   Full directory path of the package to examine
1582
#
1583
# Returns         : Nothing
1584
#
1585
sub IncludePkg
1586
{
1587
    my ($name, $pkg) = @_;
1588
    my $file = "$pkg/incpkg";
1589
 
363 dpurdie 1590
    Debug ("IncludePkg: $name, $pkg" );
227 dpurdie 1591
 
1592
    #
1593
    #   Using a require will ensure that the package is only processed once
1594
    #   even though the function user may be called multiple times.
1595
    #   Also prevents recursion within included packages.
1596
    #
1597
    if ( -f $file  )
1598
    {
261 dpurdie 1599
        Log( "PackageIncludes. $name" ) unless ( $INC{$file} );
227 dpurdie 1600
        require $file;
1601
    }
1602
}
1603
 
1604
 
1605
sub LinkSandbox
1606
{
1607
    my( $name, $path, $platform ) = @_;
1608
    return if ( $Clobber );                     # clobber mode ?
2078 dpurdie 1609
 
371 dpurdie 1610
    Warning ("LinkSandbox() This directive is being deprecated.");       #Dec-2011
227 dpurdie 1611
 
1612
    Error ("LinkSandbox() expects three arguments:  @_")
1613
        unless ( $#_ == 2 );
1614
 
371 dpurdie 1615
    Error ("LinkSandbox not allowed in ABT build","It can only be used in a Development Environment")
299 dpurdie 1616
        if ( $::GBE_ABT );
1617
 
227 dpurdie 1618
    Debug( "LinkSandbox:" );
1619
    Debug( "Package:   $name" );
1620
    Debug( "Version:   $path" );
1621
 
1622
    DataDirective("LinkSandbox");               # This directive allowed here
1623
 
2078 dpurdie 1624
    if ( $IgnorePkgs )
1625
    {
1626
        Log( "LinkSandbox. $name ($path) - Ignored" );
1627
        return;
1628
    }
1629
 
227 dpurdie 1630
#
1631
#   If GBE_BUILDFILTER exists, Import 'user' platform
1632
#   specification and filter against the BUILD_ACTIVEPLATFORMS.
1633
#
261 dpurdie 1634
    Log( "LinkSandbox. $name ($path)" );
227 dpurdie 1635
 
1636
    if ( ! -d $path )                           # sandbox exists ?
1637
    {
261 dpurdie 1638
        Log( "WARNING .... Sandbox $path not available" );
227 dpurdie 1639
    }
1640
    else
1641
    {
363 dpurdie 1642
        my @platforms;
1643
        if ( !defined($platform) || $platform eq "*" ) {
1644
            @platforms = @BUILD_ACTIVEPLATFORMS;
1645
        } else {
1646
            @platforms = ExpandPlatforms( split( ',', $platform ) );
1647
        }
1648
 
227 dpurdie 1649
        $path = Realpath( $path );
363 dpurdie 1650
        IncludePkg ( $name, $path );
1651
        foreach my $platform ( @platforms )
227 dpurdie 1652
        {
363 dpurdie 1653
            LinkEntry( $platform, $path, $name, "!sandbox", 1, 1 );
227 dpurdie 1654
        }
1655
    }
1656
}
1657
 
1658
 
1659
#-------------------------------------------------------------------------------
1660
# Function        : LinkPkgArchive
1661
#
1662
# Description     : Include an external package into the build sandbox
1663
#                   by extending the compiler and linker search paths to
1664
#                   include suitable directories found in the package
1665
#
1666
# Inputs          : package name
1667
#                   package version
1668
#
1669
sub LinkPkgArchive
1670
{
1671
    my( $name, $version ) = @_;
1672
 
1673
    return BuildPkgArchive( @_ )
1674
        if ( $ForceBuildPkg );                  # Forcing interface directory
1675
    return if ( $Clobber );                     # clobber mode ?
1676
 
1677
    Debug( "LinkPkgArchive:" );
1678
    Debug( "Name:      $name" );
1679
    Debug( "Version:   $version" );
1680
 
1681
    DataDirective("LinkPkgArchive");            # This directive allowed here
1682
 
2078 dpurdie 1683
    if ( $IgnorePkgs )
1684
    {
1685
        Log( "LinkPkgArchive .. $name ($version) - Ignored" );
1686
        return;
1687
    }
1688
 
227 dpurdie 1689
    #
1690
    #   Ensure that we have do not have multiple definitions
1691
    #
1692
    if ( PackageEntry::Exists( $name, $version ) )
1693
    {
261 dpurdie 1694
        Log( "Duplicate Package: $name, $version. Duplicate entry ignored" );
227 dpurdie 1695
        return;
1696
    }
1697
 
1698
    if ( $Cache && $::GBE_DPKG_CACHE )
1699
    {
1700
        my $mode = ($Cache > 1) ? "-refresh" : "";
331 dpurdie 1701
        Log( "LinkPkgArchive .. $name ($version) Update Cache" );
227 dpurdie 1702
        System('--NoExit', "$::GBE_PERL $::GBE_TOOLS/cache_dpkg.pl $mode -quiet $name/$version" );
1703
    }
1704
 
1705
    #
1706
    #   Locate the package ONCE
1707
    #
331 dpurdie 1708
    Log( "LinkPkgArchive .. $name ($version)" );
227 dpurdie 1709
    my ($pkg, $local ) = PackageLocate( $name, $version );
1710
    if ( $pkg )
1711
    {
1712
        #
1713
        #   Generate package rules for each active platform
1714
        #
363 dpurdie 1715
        IncludePkg ( $name, $pkg );
1716
        foreach my $platform ( @BUILD_ACTIVEPLATFORMS, '--' )
227 dpurdie 1717
        {
331 dpurdie 1718
            LinkEntry( $platform, $pkg, $name, $version, 0, $local );
227 dpurdie 1719
        }
1720
    }
1721
}
1722
 
1723
#-------------------------------------------------------------------------------
1724
# Function        : PackageLocate
1725
#
1726
# Description     : Locate a package
1727
#                   Once located a package will be processed for each
1728
#                   platform, but it need only be located ONCE
1729
#
1730
# Inputs          : package name
1731
#                   package version
1732
#
1733
# Returns         : path to the package
1734
#                   local       1 - From local package repository
1735
#
1736
sub PackageLocate
1737
{
1738
    my ($name, $uversion ) = @_;
283 dpurdie 1739
    my $pkg;
227 dpurdie 1740
    my $local = 1;
359 dpurdie 1741
    my $sandbox = ! $sandbox_exact;
227 dpurdie 1742
    my $isa_cache = 0;
1743
    my $version;
1744
 
1745
    Debug( "PackageLocate: ($name/$uversion)" );
1746
 
1747
    #
1748
    #   Look in each package archive directory
1749
    #
1750
    foreach my $dpkg ( split( $::ScmPathSep, $::GBE_DPKG_SBOX),
1751
                       '--NotSandbox',
1752
                       split( $::ScmPathSep, $::GBE_DPKG_LOCAL),
1753
                       '--NotLocal',
1754
                       split( $::ScmPathSep, $::GBE_DPKG_CACHE),
1755
                       '--NotCache',
4688 dpurdie 1756
                       split( $::ScmPathSep, $::GBE_DPKG_REPLICA),
227 dpurdie 1757
                       split( $::ScmPathSep, $::GBE_DPKG),
313 dpurdie 1758
                       split( $::ScmPathSep, $::GBE_DPLY),
227 dpurdie 1759
                       split( $::ScmPathSep, $::GBE_DPKG_STORE) )
1760
    {
1761
 
1762
        #
1763
        #   Detect various tags that have been placed in the search list
1764
        #   to flag the end of the sandbox search and the end of the local
1765
        #   archive search
1766
        #
1767
        if ( $dpkg eq '--NotSandbox' )
1768
        {
1769
            $sandbox = 0;
1770
            next;
1771
        }
1772
        if ( $dpkg eq '--NotLocal' )
1773
        {
1774
            $local = 0;
1775
            $isa_cache = 1;
1776
            next;
1777
        }
1778
        if ( $dpkg eq '--NotCache' )
1779
        {
1780
            $isa_cache = 0;
1781
            next;
1782
        }
1783
 
1784
 
1785
        #
1786
        #   If we are playing in a sandbox, then the version number is
1787
        #   not used. The Package suffix is still used so that we can
1788
        #   differentiate sysbasetypes.xxxxx.mas and sysbasetypes.xxxxx.syd
1789
        #
1790
        if ( $sandbox )
1791
        {
359 dpurdie 1792
            my ($pn, $pv, $ps ) = SplitPackage ($name, $uversion );
227 dpurdie 1793
            $version = 'sandbox';
1794
            $version .= '.' . $ps if ( $ps );
1795
        }
1796
        else
1797
        {
1798
            $version = $uversion;
1799
        }
1800
 
1801
        #
1802
        #   Alias support
1803
        #   If the 'version' is '!current' then use a version of:
1804
        #       current
1805
        #       current_<USER_NAME>
1806
        #   This is an old mechanism whose use should not be encouraged
1807
        #
1808
        #..
1809
        if ( $version eq "!current" )
331 dpurdie 1810
        {
1811
            Error ("Use of !version is not allowed in ABT build")
1812
                if ( $::GBE_ABT );
227 dpurdie 1813
 
331 dpurdie 1814
            $pkg = "$dpkg/$name/current";       # current
227 dpurdie 1815
            $pkg = "$dpkg/$name/current.lnk"
1816
                if ( -e "$dpkg/$name/current.lnk" );
1817
 
331 dpurdie 1818
                                                # USER specific current
1819
            EnvImport( "USER" );
227 dpurdie 1820
            $pkg = "$dpkg/$name/current_$::USER"
1821
                if ( -e "$dpkg/$name/current_$::USER" );
1822
 
1823
            $pkg = "$dpkg/$name/current_$::USER.lnk"
1824
                if ( -e "$dpkg/$name/current_$::USER.lnk" );
1825
        }
1826
        else
1827
        {                                       # standard
1828
            $pkg = "$dpkg/$name/$version";
1829
            $pkg = "$dpkg/$name/$version.lnk"
1830
                if ( -e "$dpkg/$name/$version.lnk" );
1831
        }
1832
 
1833
        #
1834
        #   Using a soft link
1835
        #   Emulate a link in software. The link file contains one line
1836
        #   which is the real pathname of the package
1837
        #
1838
        if ( $pkg =~ m~(.*)\.lnk$~  )
1839
        {
1840
            #
1841
            #   Warn the user if both a link and a real directory
1842
            #   are both present - the link may well be incorrect
1843
            #
1844
            my $non_link = $1;
1845
            Warning ("Suspect package link: $pkg",
1846
                     "Both a link and a package where found - using the link" )
1847
                                                            if ( -d $non_link );
1848
 
1849
            Debug( "           link found -> $pkg" );
1850
            my $link_src = $pkg;
283 dpurdie 1851
            open( LNKFILE, '<', "$pkg" ) || Error( "cannot open '$pkg'" );
227 dpurdie 1852
            $pkg = <LNKFILE>;                   # real path
1853
            close( LNKFILE );
1854
            $pkg = '' unless ( $pkg );
325 dpurdie 1855
            $pkg =~ s~\s+$~~;;
371 dpurdie 1856
            $pkg =~ s~^GBE_SANDBOX/~$::GBE_SANDBOX/~;
227 dpurdie 1857
 
2078 dpurdie 1858
            unless ( -d $pkg )
1859
            {
1860
                Error ("Broken link: $pkg",
1861
                       "Source link: $link_src",
1862
                       "Try deleting the .lnk file" ) unless ( $NoPackageError );
1863
 
1864
                Warning ("Package not available. Broken link: $pkg");
1865
            }
227 dpurdie 1866
        }
1867
 
1868
        Debug( "           searching $pkg" );
1869
 
1870
        #   Does the package directory exist?
1871
        #   Terminate the directory name with a "/" to detect hidden spaces
1872
        #..
1873
        $pkg =~ s~//~/~g;
1874
        next unless ( -d "$pkg/" );             # exists ?
1875
 
1876
        #
1877
        #   If the package exists within the dpkg_archive cache then mark the
1878
        #   version as having been used. Used by cache cleanup algorithms
1879
        #
1880
        if ( $isa_cache  )
1881
        {
1882
            TouchFile ( "$pkg/used.cache", "Marks the cache copy as being used");
1883
        }
1884
 
1885
        #
1886
        #   Use the first suitable package found
1887
        #..
1888
 
1889
        Debug( "           importing $pkg" );
1890
        return $pkg, $local;
1891
    }
1892
 
1893
    #
1894
    #   Package not found
1895
    #   This is an error, although it can be bypassed
1896
    #
261 dpurdie 1897
    Error ("Required package not found: '$name/$version'" ) unless ( $NoPackageError );
227 dpurdie 1898
 
261 dpurdie 1899
    Log( "WARNING .... Package not available: '$name/$version'" );
283 dpurdie 1900
    return;
227 dpurdie 1901
}
1902
 
1903
 
1904
#-------------------------------------------------------------------------------
1905
# Function        : LinkEntry
1906
#
1907
# Description     : Scan a package an locate platform specific directories
1908
#                   Create data structures to capture the information
1909
#                   This function is used by LinkPkgArchive and LinkSandbox
1910
#                   to perfom the bulk of package inclusion work.
1911
#
1912
# Inputs          : platform being processed
1913
#                   path to the package
1914
#                   name of the package
1915
#                   version of the package
1916
#                   sandbox support (non-zero)
331 dpurdie 1917
#                   local package
227 dpurdie 1918
#
1919
sub LinkEntry
1920
{
331 dpurdie 1921
    my( $platform, $pkg, $name, $version, $sandbox, $local ) = @_;
227 dpurdie 1922
    my( $entry );
1923
 
1924
    #   Create entry record
1925
    #
1926
    #..
331 dpurdie 1927
    $entry = PackageEntry::New( $pkg, $name, $version, $sandbox, 'link', $local );
227 dpurdie 1928
 
1929
    #   Populate includes:
1930
    #
1931
    #   - include/$platform                 (eg include/solaris)
1932
    #   - inc/$platform                     (eg inc/solaris)
1933
    #   - include.$platform                 (eg include.solaris)
1934
    #   - inc.$platform                     (eg inc.solaris)
1935
    #   - include                           (eg include)
1936
    #   - inc                               (eg inc)
1937
    #
1938
    #   plus, product specialisation directores
1939
    #
1940
    #   eg. BuildProduct( 'IDFC', 'WIN32' );
1941
    #
1942
    #   - inc/IDFC_WIN32                    <- derived platform
1943
    #   - inc/IDFC                          <- product
1944
    #   - inc/WIN32                         <- target
1945
    #..
1946
    my $parts = $BUILDINFO{$platform}{PARTS};
1947
 
1948
    foreach my $part ( @$parts )
1949
    {
1950
        $entry->RuleInc( "/include." . $part ) if ( !$sandbox );
1951
        $entry->RuleInc( "/inc." . $part )     if ( !$sandbox );
1952
        $entry->RuleInc( "/include/" . $part ) if ( !$sandbox );
1953
        $entry->RuleInc( "/inc/" . $part );
1954
    }
1955
 
1956
    #
1957
    #   Also search the root include directory - last
1958
    #
1959
    $entry->RuleInc( "/include" )               if ( !$sandbox );
1960
    $entry->RuleInc( "/inc" );
1961
 
1962
    #   Populate libraries:
1963
    #
1964
    #   - lib/lib.$platform[D|P]            (eg lib/lib.sparcD)
1965
    #   - lib/$platform[D|P]                (eg lib/lib.sparc)
1966
    #   - lib.$platform[D|P]                (eg lib.sparcD)
1967
    #
1968
    #   plus, product specialisation directores
1969
    #
1970
    #   eg. BuildProduct( 'IDFC', 'WIN32' );
1971
    #
1972
    #   - lib/IDFC_WIN32                    <- derived platform
1973
    #   - lib/IDFC                          <- product
1974
    #   - lib/WIN32                         <- target
1975
    #..
1976
    $parts = $BUILDINFO{$platform}{PARTS};
1977
 
1978
    foreach my $part ( @$parts )
1979
    {
1980
        $entry->RuleLib("/lib" . ".$part" )     if ( !$sandbox );
1981
        $entry->RuleLib("/lib" . "/lib.$part" ) if ( !$sandbox );
1982
        $entry->RuleLib("/lib" . "/$part" );
1983
    }
1984
 
1985
    #
1986
    #   Some extra places to search
1987
    #   None. This is good as it indicates that all locations are described in PARTS
1988
    #
1989
    #   Do NOT search in /lib. There are no libraries that work on all platforms
1990
    #   Libraries are binaries!
1991
    #
1992
    #    $entry->RuleLib( "/lib" );
1993
 
1994
    #   Tools:
1995
    #
1996
    #   Tools provide an extensible search path for tools and
1997
    #   utilities used to build programs. These are tools that
1998
    #   are executable on the current host machine and are
1999
    #   independent of the toolset.
2000
    #
2001
    #..
2002
    $entry->ExamineToolPath();
2003
    $entry->ExamineThxPath($platform);
2004
    $entry->Cleanup();                          # cleanup tables
2005
 
2006
    #
2007
    #   Add the package entry to the array of such entries for
2008
    #   the current platform. Maintain the discovery order
2009
    #
2010
    #..
2011
    push ( @{$PKGRULES{$platform}}, $entry );
2012
}
2013
 
2014
 
2015
#-------------------------------------------------------------------------------
2016
# Function        : BuildPkgArchive
2017
#
2018
# Description     : Include an external package into the build sandbox
2019
#                   by copying the packages files into the interface directory
2020
#
2021
# Inputs          : package name
2022
#                   package version
2023
#
2024
sub BuildPkgArchive
2025
{
2026
    my( $name, $version ) = @_;
2027
 
2028
    return if ( $Clobber );                     # clobber mode ?
2029
 
2030
    Debug( "BuildPkgArchive:" );
2031
    Debug( "Name:      $name" );
2032
    Debug( "Version:   $version" );
2033
 
2034
    DataDirective("BuildPkgArchive");           # This directive allowed here
2035
 
2078 dpurdie 2036
    if ( $IgnorePkgs )
2037
    {
2038
        Log( "BuildPkgArchive . $name ($version) - Ignored" );
2039
        return;
2040
    }
2041
 
227 dpurdie 2042
    #
2043
    #   Ensure that we have do not have multiple definitions
2044
    #
2045
    if ( PackageEntry::Exists( $name, $version ) )
2046
    {
261 dpurdie 2047
        Log( "Duplicate Package: $name, $version. Duplicate entry ignored" );
227 dpurdie 2048
        return;
2049
    }
2050
 
2051
    if ( $Cache && $::GBE_DPKG_CACHE )
2052
    {
2053
        my $mode = ($Cache > 1) ? "-refresh" : "";
261 dpurdie 2054
        Log( "BuildPkgArchive . $name ($version) Update Cache" );
227 dpurdie 2055
        System('--NoExit', "$::GBE_PERL $::GBE_TOOLS/cache_dpkg.pl $mode -quiet $name/$version" );
2056
    }
2057
 
2058
    #
2059
    #   Locate the package
2060
    #   Use the first instance of the package that it found
2061
    #
261 dpurdie 2062
    Log( "BuildPkgArchive . $name ($version)" );
227 dpurdie 2063
    my ( $pkg, $local ) = PackageLocate( $name, $version );
2064
    if ( $pkg )
2065
    {
2066
        #
2067
        #   Create a Package Entry
2068
        #
331 dpurdie 2069
        my $entry = PackageEntry::New( $pkg, $name, $version, 0, 'build', $local );
227 dpurdie 2070
 
2071
        #
2072
        #   Determine if the package needs to be installed:
2073
        #       If the package is a 'local' package then force transfer
2074
        #       If the user has specified --cache then force transfer
2075
        #       If package is newer that copy, then force transfer
2076
        #       If copy does not exist, then force a transfer
2077
        #
2078
        my $tag_dir = "$Cwd/$BUILDINTERFACE/BuildTags";
2079
        my $tag_file = "$tag_dir/${name}_${version}.tag";
2080
 
2081
        my $package_installed;
2082
        $package_installed = 1
2083
            if ( !$local &&
2084
                 !$Cache &&
2085
                 !FileIsNewer( $entry->GetBaseDir('descpkg'), $tag_file ) );
2086
 
2087
        #
2088
        #   Determine the package format and use the appropriate installer
2089
        #   Supported formats
2090
        #       1) Package has a descpkg file (new style)
2091
        #       2) Package has a InstallPkg.sh file (old style)
2092
        #       3) Package has a Install.sh file (old style is it used ??)
2093
        #
2094
        if ( $package_installed ) {
2095
            Verbose ("Package already installed: $name, $version");
2096
 
2097
        } else {
261 dpurdie 2098
            Log( "                . installing '$pkg'" );
2099
            Log( "                . -> " . readlink($pkg) ) if ( -l $pkg );
227 dpurdie 2100
 
2101
            if ( -e "$pkg/descpkg" )
2102
            {
2103
 
2104
                #
2105
                #   If forcing a BuildPkg, then don't use symlinks
2106
                #   to files in dpkg_archive
2107
                #
331 dpurdie 2108
                my @opts;
2109
                push @opts, "--NoSymlinks" if ( $ForceBuildPkg );
2110
                push @opts, "--AllowOverWrite" if ( $local );
227 dpurdie 2111
 
2112
                #
2113
                #   Determine all the Platforms, Products and Targets
2114
                #   that need to be installed
2115
                #
2116
                my $arglist = GenerateInstallArgumentList();
331 dpurdie 2117
                System( "cd $pkg; $::GBE_PERL $::GBE_TOOLS/installpkg.pl $Cwd/$BUILDINTERFACE $Cwd @opts $arglist");
227 dpurdie 2118
                Error( "Package installation error" ) if ( $? != 0 );
2119
            }
2120
            elsif ( -e "$pkg/InstallPkg.sh" )
2121
            {
2122
                System( "(cd $pkg; ./InstallPkg.sh $Cwd/$BUILDINTERFACE $Cwd)" );
2123
            }
2124
            elsif ( -e "$pkg/Install.sh" )
2125
            {
2126
                System( "(cd $pkg; ./Install.sh $Cwd/$BUILDINTERFACE $Cwd)" );
2127
            }
2128
            else
2129
            {
2130
                Error ("Unknown package format for package $name/$version found in $pkg");
2131
            }
2132
 
2133
            #
2134
            #   Tag the package as installed - after it has been transferred
2135
            #
2136
            mkdir ( $tag_dir );
2137
            TouchFile( $tag_file );
2138
        }
2139
 
2140
        #
2141
        #   Process package
2142
        #
2143
        IncludePkg ( $name, $pkg );
2144
 
2145
        #
2146
        #   Complete the creation of the package entry
2147
        #   Add the information for all platforms
2148
        #
2149
        $entry->Cleanup();
2150
        for my $platform (@BUILD_ACTIVEPLATFORMS)
2151
        {
2152
            $entry->ExamineToolPath();
2153
            $entry->ExamineThxPath($platform);
2154
            push ( @{$PKGRULES{$platform}}, $entry );
2155
        }
2156
    }
2157
}
2158
 
2159
#-------------------------------------------------------------------------------
311 dpurdie 2160
# Function        : CreateInterfacePackage
2161
#
2162
# Description     : Create a dummy package entry to describe the Interface
2163
#                   This is done AFTER all the BuildPkgArchive directives have
2164
#                   been processed so that the interface directory is fully
2165
#                   processed
2166
#
2167
# Inputs          : None
2168
#
2169
# Returns         : 
2170
#
2171
sub CreateInterfacePackage
2172
{
2173
    foreach my $platform ( @BUILD_ACTIVEPLATFORMS )
2174
    {
2175
        my $entry = PackageEntry::Interface( "$::Cwd/$BUILDINTERFACE" );
2176
 
2177
        #
2178
        #   Locate include and lib bits within the interface
2179
        #   This is much simpler than for a LinkPkgArchive as the form
2180
        #   has been sanitized
2181
        #
2182
        my $parts = $BUILDINFO{$platform}{PARTS};
2183
 
2184
        foreach my $part ( @$parts )
2185
        {
2186
            $entry->RuleInc( "/include/" . $part );
2187
        }
2188
        $entry->RuleInc( "/include" );
2189
 
2190
        foreach my $part ( @$parts )
2191
        {
2192
            $entry->RuleLib("/lib/" . $part );
2193
        }
2194
 
2195
        $entry->ExamineToolPath();
2196
        $entry->ExamineThxPath($platform);
2197
        $entry->Cleanup();
2198
 
2199
        #
2200
        #   Add the package entry to the array of such entries for
2201
        #   the current platform. Force it to be the first one as
2202
        #   the interface directory will be scanned first
2203
        #
2204
        unshift ( @{$PKGRULES{$platform}}, $entry );
2205
    }
2206
}
2207
 
2208
#-------------------------------------------------------------------------------
227 dpurdie 2209
# Function        : GenerateInstallArgumentList
2210
#
2211
# Description     : Generate an argument list for the installpkg.pl script
2212
#                   The argument list is of the form
2213
#                       --Platform:xx[:xx[:xx]] --Platform:yy[:yy[:yy]] ...
2214
#                   Where xx is:
2215
#                       * a 'part' of the target platform
2216
#                         Order is: platform, product, ...  target( in that order )
2217
#                       * --Option[=yyy]
2218
#                        An option to be passed to the script. These are bound only
2219
#                        to the enclosed platform.
2220
# Inputs          :
2221
#
2222
# Returns         : See above
2223
#
2224
sub GenerateInstallArgumentList
2225
{
2226
    my @arglist;
2227
 
2228
    #
2229
    #   Generate the argument list as an array
2230
    #
2231
    for (@BUILD_ACTIVEPLATFORMS)
2232
    {
2233
        my @args = '--Platform';
2234
        push @args, @{$BUILDINFO{$_}{PARTS}};
2235
        push @arglist, join (":" , @args );
2236
    }
2237
 
2238
    return "@arglist";
2239
}
2240
 
2241
#-------------------------------------------------------------------------------
2242
# Function        : GeneratePlatformList
2243
#
2244
# Description     : Return a list of platforms that should particiate in this
2245
#                   build. This is a function of
2246
#                       1) Platforms defined in the build.pl file
5679 dpurdie 2247
#                       2) Platforms excluded in the build.pl file
2248
#                       3) User filter defined in GBE_BUILDFILTER
227 dpurdie 2249
#
2250
#                   The primary use of this function is to limit the creation
2251
#                   of makefiles to those that have supported compilers on
2252
#                   the underlying machine.
2253
#
2254
#                   GBE_BUILDFILTER is a space seperated string of words
2255
#                   Each word may be one of
2256
#                       OPTION=TAG or OPTION=!TAG
2257
#                       TAG or !TAG. This is the same as --TARGET=TAG
2258
#
2259
#                   Bare tags are taken to be TARGETS.
2260
#
2261
#                   Where OPTION may be one of
2262
#                       --PLATFORM
2263
#                       --PRODUCT
2264
#                       --TARGET
5679 dpurdie 2265
#                   For a BuildProduct( AA,BB,CC)
2266
#                       Product     - AA
2267
#                       Targets     - BB, CC
2268
#                       Platforms   - AA_BB, AA_CC
227 dpurdie 2269
#
2270
#                   Special cases
2271
#                   1) If GBE_BUILDFILTER is empty, then all available platforms are used
2272
#                      The global $All is set, then all available platforms are used
2273
#                   2) If the first word of GBE_BUILDFILTER is a negative filter,
2274
#                      ie is used the !xxxx or yyy=!xxxx construct, then it is assumed
2275
#                      that the filter will start with all available platforms
2276
#                   3) The special word --ALL forces selection of ALL platforms
2277
#                      and may reset any existing scanning
2278
#                   4) GBE_BUILDFILTER is parsed left to right. It is possible to add and
2279
#                      subtract items from the list.
2280
#                   5) OPTIONS are case insensitive
2281
#                      TAGS are case sensitive
2282
#
2283
#
2284
# Inputs          : GBE_BUILDFILTER from the environment
2285
#
2286
# Returns         : An array of platforms to include in the build
2287
#                   Maintains @BUILD_ACTIVEPLATFORMS  - the last calculated result
2288
#                   Ensures that @DEFBUILDPLATFORMS is a subset of @BUILD_ACTIVEPLATFORMS
2289
#
2290
sub GeneratePlatformList
2291
{
2292
    #
2293
    #   Return the cached result for speed
2294
    #   The value need only be calculated once
2295
    #
2931 dpurdie 2296
    unless ( @BUILD_ACTIVEPLATFORMS )
227 dpurdie 2297
    {
2298
        my ($platform_filter);
2299
        my %result;
2300
        my %part_to_platform;
2301
 
2302
        #
2303
        #   Create a data structure to assist in the production of the platform list
2304
        #   The structure will be a hash of hashes of arrays
2305
        #
2306
        #   The first level hash will be keyed by the word TARGET, PRODUCT or PLATFORM
2307
        #   The second level of the hash will keyed by available targets, products or platforms
2308
        #   The value of the field will be an array of platforms that match the keyword
2309
        #
2310
        for my $platform (keys (%::BUILDINFO))
2311
        {
2312
            my $pParts = $::BUILDINFO{$platform};
2313
 
2314
            #
2315
            #   Skip platforms that are known to be unavailable on this build
2316
            #   machine. Self configure
2317
            #
2318
            next if ( $pParts->{NOT_AVAILABLE} );
2319
 
2320
            my $target  = $pParts->{TARGET};
2321
            my $product = $pParts->{PRODUCT};
2322
 
2323
            push @{$part_to_platform{'PLATFORM'}{$platform}}, $platform;
2324
            push @{$part_to_platform{'TARGET'}  {$target}}  , $platform;
2325
            push @{$part_to_platform{'PRODUCT'} {$product}} , $platform;
2326
        }
2327
        #
2328
        #   Determine the source of the filter
2329
        #   If the user provides one, then use it.
2330
        #   Otherwise its taken from the environment.
2331
        #
2332
        #   Global build all platforms - Kill any user filter
2333
        #
2334
        if ( $All )
2335
        {
2336
            $platform_filter = "";
2337
        }
2338
        else
2339
        {
2340
            $platform_filter = "";
2341
            $platform_filter = $::GBE_BUILDFILTER
2342
                if ( defined($::GBE_BUILDFILTER) );
2343
        }
2344
        Debug( "GeneratePlatformList: Filter:$platform_filter" );
2345
 
2346
        #
2347
        #   Detect the special cases
5679 dpurdie 2348
        #       1) No user definition
227 dpurdie 2349
        #       2) First word contains a subtractive element
5679 dpurdie 2350
        #   And assume all platforms    
227 dpurdie 2351
        #
2352
        my (@filter) = split( ' ', $platform_filter );
2353
 
2354
        if ( !scalar @filter || $filter[0] =~ m/^$/ || $filter[0] =~ m/!/ )
2355
        {
2356
            %result = %{$part_to_platform{'PLATFORM'}}
2357
                if exists $part_to_platform{'PLATFORM'} ;
2358
        }
5679 dpurdie 2359
 
227 dpurdie 2360
#DebugDumpData( "PartToPlatform", \%part_to_platform );
2361
 
2362
        #
2363
        #   Process each element in the user filter list
2364
        #   Expand platforms into known aliases
2365
        #
2366
        for my $word (@filter)
2367
        {
2368
            my $platform;
2369
 
2370
            if ( $word =~ m/^--ALL/i )
2371
            {
2372
                %result = %{$part_to_platform{'PLATFORM'}};
2373
            }
2374
            elsif ( $word =~ m/^--(TARGET)=(!?)(.*)/i ||
2375
                    $word =~ m/^--(PRODUCT)=(!?)(.*)/i ||
2376
                    $word =~ m/^--(PLATFORM)=(!?)(.*)/i ||
2377
                    ( $word !~ m/^-/ && $word =~ m/()(!?)(.*)/ )
2378
                )
2379
            {
2380
                my $table = uc($1);
2381
                $table = "TARGET"
2382
                    unless ( $1 );
2383
 
2384
                #
2385
                #   Expand PLATFORMs into known aliases
2386
                #   Alias will expand to PLATFORMs so it won't work unless we are
2387
                #   processing PALTFORMs.
2388
                #
2389
                my @taglist = ( $table eq "PLATFORM" ) ? ExpandPlatforms($3) : $3;
2390
 
2391
                #
2392
                #   Add / Remove items from the result
2393
                #
2394
                for my $item ( @taglist )
2395
                {
2396
                    my $plist = $part_to_platform{$table}{$item};
2397
                    for ( @{$plist})
2398
                    {
2399
                        if ( $2 )
2400
                        {
2401
                            delete $result{$_};
2402
                        }
2403
                        else
2404
                        {
2405
                            $result{$_} = 1;
2406
                        }
2407
                    }
2408
                }
2409
            }
2410
            else
2411
            {
2412
                print "GBE_BUILDFILTER filter term not understood: $word\n";
2413
            }
2414
        }
2415
 
2416
        #
5679 dpurdie 2417
        #   Process BuildExclude
2418
        #   A list of 
2419
        #
2420
        for my $word (@BUILDEXCLUDE)
2421
        {
2422
            my $platform;
2423
 
2424
            Error('BuildExclude: Unknown option: ' . $word) if ($word =~ m~^-~);
2425
            Error('BuildExclude: Invalid format: ' . $word) if ($word =~ m~^!~);
2426
 
2427
            #
2428
            #   Remove items from the result
2429
            #
2430
            my $table = "TARGET";
2431
            my $plist = $part_to_platform{$table}{$word};
2432
            Warning('BuildExclude: Unknown target:' . $word ) unless $plist;
2433
            for ( @{$plist})
2434
            {
2435
                delete $result{$_};
2436
            }
2437
        }
2438
 
2439
        #
227 dpurdie 2440
        #   Return an array of platforms to process
2441
        #
2442
        @BUILD_ACTIVEPLATFORMS = sort keys %result;
2443
 
2444
        #
2445
        #   Ensure that DEFBUILDPLATFORMS is a subset of build active platforms
2446
        #
2447
        my @NEW_DEFBUILDPLATFORMS;
2448
        foreach ( @DEFBUILDPLATFORMS )
2449
        {
2450
            push @NEW_DEFBUILDPLATFORMS, $_
2451
                if ( exists $result{$_} );
2452
        }
2453
        @DEFBUILDPLATFORMS = @NEW_DEFBUILDPLATFORMS;
2454
    }
2455
 
2456
    Debug("GeneratePlatformList: Result:@BUILD_ACTIVEPLATFORMS");
2457
    return @BUILD_ACTIVEPLATFORMS;
2458
}
2459
 
2460
#-------------------------------------------------------------------------------
2461
# Function        : PrintPlatforms
2462
#
2463
# Description     : Petty print the specified platform list, breaking line
2464
#                   on either a primary key change or length width >78.
2465
#
2466
# Returns         : Formated string
2467
#
2468
# Example Output :
2469
#
2470
#           DDU_LMOS_WIN32 DDU_LMOS_linux_armv4 DDU_LMOS_linux_i386
2471
#           IDFC_LMOS_WIN32 IDFC_LMOS_linux_armv4 IDFC_LMOS_linux_i386
2472
#           LMOS_WCEPSPC_ARM LMOS_WCEPSPC_EMU LMOS_WIN32 LMOS_linux_armv4
2473
#           LMOS_linux_i386
2474
#..
2475
sub PrintPlatforms
2476
{
2477
    my ($platforms, $nl) = @_;
2478
    my ($string) = "";                          # result
2479
 
2931 dpurdie 2480
    if ( @$platforms )
227 dpurdie 2481
    {
2482
        my ($key_run) = 0;
2483
        my ($pkey);                             # previous key
2484
 
2485
        #   Perform a simple formatting and determine if there is key 
2486
        #   change greater then 1 or whether the total length exceeds 78.
2487
        #
2488
        #   If the line exceeds 78, the printer shall then reformat 
2489
        #   breaking based on line length and possiblity keys.
2490
        #
2491
        $pkey = "";
2492
        for my $k (sort @$platforms) 
2493
        {
2494
            my ($d);                            # delimitor
2495
 
2496
            if (($d = index( $k, '_' )) != index( $pkey, '_' ) ||
2497
                    substr( $k, 0, $d ) ne substr( $pkey, 0, $d )) {
2498
                $key_run = 1
2499
                    if ($key_run <= 1);         # change, reset run if <= 1
2500
            } else {
2501
                $key_run++;                     # same primary key
2502
            }
2503
 
2504
            $string .= " " if ($pkey);
2505
            $string .= $k;
2506
            $pkey = $k;
2507
        }
2508
 
2509
        #   Reprint if required.
2510
        #
2511
        if (length($nl)+length($string) > 78)
2512
        {
2513
            my ($llen);                         # line length
2514
 
2515
            $llen = length($nl);
2516
 
2517
            $pkey = "";
2518
            $string = "";
2519
 
2520
            for my $k (sort @$platforms)
2521
            {
2522
                my ($klen, $d);                 # key length, delimitor
2523
 
2524
                $klen = length($k);
2525
                if ($pkey ne "")
2526
                {
2527
                    if ($llen + $klen > 78 ||
2528
                        ($key_run > 1 && (
2529
                            ($d = index( $k, '_' )) != index( $pkey, '_' ) ||
2530
                            substr( $k, 0, $d ) ne substr( $pkey, 0, $d ) )) )
2531
                    {                           # line >70 or key change
2532
                        $string .= $nl;
2533
                        $llen = length($nl);
2534
                    }
2535
                    else
2536
                    {
2537
                        $string .= " ";
2538
                        $llen++;
2539
                    }
2540
                }
2541
                $string .= $k;
2542
                $pkey = $k;
2543
                $llen += $klen;
2544
            }
2545
        }    
2546
    }
2547
    return $string;
2548
}
241 dpurdie 2549
#-------------------------------------------------------------------------------
2550
# Function        : PrintList
2551
#
2552
# Description     : Pretty format an array to fit within 80 char line
2553
#                   Perform wrapping as required
2554
#
2555
# Inputs          : $list           - Reference to an array
2556
#                   $nl             - New line stuff.
2557
#                                     Use to prefix new lines
2558
#
2559
# Returns         : string
2560
#
2561
sub PrintList
2562
{
2563
    my ($list, $nl) = @_;
2564
    my ($string) = '';                          # result
2565
    my $sep;
227 dpurdie 2566
 
241 dpurdie 2567
    if ( @$list )
2568
    {
2569
        my ($llen) = length($nl);
227 dpurdie 2570
 
241 dpurdie 2571
        for my $k (@$list)
2572
        {
2573
            my $klen = length($k);
2574
            if ($llen + $klen > 78 )
2575
            {
2576
                $string .= $nl;
2577
                $llen = length($nl);
2578
            }
2579
            else
2580
            {
2581
                if ( $sep )
2582
                {
2583
                    $string .= $sep;
2584
                    $llen++;
2585
                }
2586
                else
2587
                {
2588
                    $sep = ' ';
2589
                }
2590
            }
2591
            $string .= $k;
2592
            $llen += $klen;
2593
        }
2594
    }
2595
    return $string;
2596
}
2597
 
305 dpurdie 2598
#-------------------------------------------------------------------------------
2599
# Function        : BuildReleaseFile
2600
#
2601
# Description     : Legacy function
2602
#                   Don't know what it was meant to do
2603
#                   Unfortunately it is present in a lot of build.pl files
2604
#
2605
#                   Not well supported on all machine types
2606
#
331 dpurdie 2607
# Inputs          : None that are used
305 dpurdie 2608
#
331 dpurdie 2609
# Returns         : Undefined
305 dpurdie 2610
#
227 dpurdie 2611
sub BuildReleaseFile
2612
{
2613
}
2614
 
305 dpurdie 2615
#-------------------------------------------------------------------------------
2616
# Function        : BuildSnapshot
2617
#
2618
# Description     : Legacy function
2619
#                   Don't know what it was meant to do
2620
#                   Unfortunately it is present in a lot of build.pl files
2621
#
2622
# Inputs          : None that are used
2623
#
2624
# Returns         : Undefined
2625
#
227 dpurdie 2626
sub BuildSnapshot
2627
{
2628
}
2629
 
305 dpurdie 2630
#-------------------------------------------------------------------------------
2631
# Function        : BuildSrcArchive
2632
#
2633
# Description     : Create a source snapshot of the build source
2634
#                   Designed to provide a source image for packaging
2635
#                   examples
2636
#
2637
#                   Should be platform independent
2638
#
2639
#                   Creates an archive file and places it into the
2640
#                   interface directory. The archive will be packaged
2641
#                   automatically by the build process
2642
#
2643
#                   Use the 'pax' utility
2644
#                       1) Can massage the file path such that the stored
2645
#                          directory image contains the package name and version
2646
#
2647
#                   Directive can be used at any time before the BuildMake
2648
#
2649
#                   Will handle the existence of an auto.pl file by inserting
2650
#                   it as build.pl.
2651
#
2652
# Inputs          : Options
2653
#
2654
#
2655
# Returns         : 
2656
#
2657
sub BuildSrcArchive
2658
{
2659
    #
2660
    #   If we are clobbering, then there is nothing to do
2661
    #   The generated file is placed within the interface
2662
    #   directory and that directory will be deleted during the clobber
2663
    #
2664
    return if ( $Clobber );
2665
    DataDirective("BuildSrcArchive");
227 dpurdie 2666
 
305 dpurdie 2667
    #
2668
    #   Currently this operation is only supported of some platforms
2669
    #   Only supported on Unix platforms
2670
    #   Uses the 'pax' utility
2671
    #
2672
    unless ( LocateProgInPath ( 'pax', '--All' ) && ( $ScmHost eq "Unix" ) )
2673
    {
2674
        Log( "SrcPackage . Not supported" );
2675
        return;
2676
    }
2677
 
2678
    #
2679
    #   Only allow one instance of the directive
2680
    #
2681
    Error ("Multiple BuildSrcArchive directives not supported")
2682
        if ( $build_source_pkg );
2683
 
2684
    #
2685
    #   Create the name of the archive
2686
    #       Based on the package name and version
2687
    #       Has no spaces
2688
    #
2689
    my $build_name = $BUILDNAME;
2690
    $build_name =~ s~\s+~_~g;
2691
 
2692
    #
2693
    #   Create the archive in the interface directory
2694
    #   Don't need to clobber it as the entire interface directory
2695
    #   will be clobbered
2696
    #
2697
    $build_source_pkg = $build_name;
2698
}
2699
 
2700
#-------------------------------------------------------------------------------
2701
# Function        : BuildSrcArchiveBody
227 dpurdie 2702
#
305 dpurdie 2703
# Description     : Function to implement the body of the BuildSrcArchive
2704
#                   operation. Will be invoked during BuildMake
2705
#
2706
# Inputs          : None
2707
#
2708
# Returns         : 
2709
#
2710
sub BuildSrcArchiveBody
2711
{
2712
    return unless ( $build_source_pkg );
2713
 
2714
    my $archive_dir = "pkg/$BUILDNAME_PACKAGE/src";
2715
    my $archive_file = "$build_source_pkg" . '.tar';
2716
 
2717
    Log( "SrcPackage . $archive_file.gz" );
2718
    unlink "$archive_dir/$archive_file";
2719
    unlink "$archive_dir/$archive_file.gz";
2720
    mkpath($archive_dir, 0, 0775);
2721
 
2722
    #
2723
    #   Create a list of files and top-level dirs to add to source archive
2724
    #   Many files are ignored
2725
    #   Should only be executed on the first 'build' thus many internal
2726
    #   directories will not be present
2727
    #
2728
    my @flist;
2729
    my $auto_pl;
2730
    opendir (my $tp, '.' ) or Error ("Cannot read current directory");
2731
    while ( $_ = readdir($tp) )
2732
    {
2733
        next if ( m/^\.$/ );
2734
        next if ( m'^\.\.$' );
2735
        next if ( m'^build\.log$' );
2736
        next if ( m'\.gbe$' );
2737
        next if ( m'^local$' );
2738
        next if ( m'^pkg$' );
2739
        next if ( m/^$BUILDINTERFACE$/ );
2740
        $auto_pl = 1, next  if ( m'^auto\.pl$' );
2741
        next if (  m'^build\.pl$' );
2742
        next if ( m/^$build_source_pkg$/ );
2743
        push @flist, $_;
2744
    }
2745
    closedir $tp;
2746
 
2747
    #
2748
    #   If we don't have an auto.pl, then we add the build.pl file
2749
    #   If we do have a auto.pl - it gets tricky. Its don't after the
2750
    #   initial pax command
2751
    #
2752
    unless ( $auto_pl )
2753
    {
2754
        push @flist, 'build.pl';
2755
    }
2756
 
2757
    #
2758
    #   Create the command to be executed
2759
    #   Prefix archive paths with build_name
2760
    #
2761
    my @command = ( 'pax', '-w', '-f', "$archive_dir/$archive_file" );
2762
    System( '--NoShell' , @command, '-s', "~^~$build_source_pkg/~", @flist );
2763
 
2764
    #
2765
    #   If we have an auto.pl file, then we need to add it to the archive
2766
    #   but it needs to be called build.pl
2767
    #
2768
    if ( $auto_pl )
2769
    {
2770
        System( '--NoShell' , @command, '-a', '-s', "~^auto.pl~$build_source_pkg/build.pl~" , 'auto.pl' );
2771
    }
2772
 
2773
    #
2774
    #   Must now zip the file
2775
    #   Can't zip and append at the same time
2776
    #
2777
    System( '--NoShell' , 'gzip', "$archive_dir/$archive_file" );
2778
 
2779
    #
2780
    #   Display the results
2781
    #
2782
    System ('--NoShell', 'pax', '-z', "-f$archive_dir/$archive_file.gz")
2783
        if (IsVerbose (1));
2784
}
2785
 
2786
#-------------------------------------------------------------------------------
2787
# Function        : BuildAccessPerms
2788
#
2789
# Description     : Check if access/permissions setting requested...
2790
#                   Legacy
2791
#
331 dpurdie 2792
#                   Don't know what it was meant to do
2793
#                   Unfortunately it is present in a lot of build.pl files
305 dpurdie 2794
#
331 dpurdie 2795
# Inputs          : None that are used
305 dpurdie 2796
#
331 dpurdie 2797
# Returns         : Undefined
2798
#
227 dpurdie 2799
sub BuildAccessPerms
2800
{
2801
}
2802
 
2803
 
2804
sub BuildSetenv
2805
{
2806
    push( @BUILDSETENV, @_ );
2807
}
2808
 
2809
#-------------------------------------------------------------------------------
2810
# Function        : DataDirective
2811
#
2812
# Description     : Called by data collection directives to ensure that we are
2813
#                   still collecting data and that we have collected other data
2814
#
2815
# Inputs          : $dname              - Directive Name
2816
#
2817
# Returns         : Will error if we are not
2818
#
2819
sub DataDirective
2820
{
2821
    my ($dname) = @_;
2822
 
2823
    Error( "$dname() must appear after BuildName()...")
2824
        if ( $BUILDNAME eq "" );
2825
 
2826
    Error( "$dname() must appear after BuildInterface()...")
2827
        unless( $BUILDINTERFACE );
2828
 
2829
    Error( "$dname() not allowed after BuildDescpkg, BuildIncpkg, BuildVersion or BuildMake")
2830
        if( $BUILDPHASE);
2831
}
2832
 
2833
#-------------------------------------------------------------------------------
2834
# Function        : StartBuildPhase
2835
#
2836
# Description     : Called by directives that deal with the building phases
2837
#                   to perform common initialisation and to ensure that
2838
#                   directives that collect data are no longer called
2839
#
305 dpurdie 2840
# Inputs          : last                - True: Last directive expected
227 dpurdie 2841
#
2842
# Returns         : May generate an error
2843
#
2844
sub StartBuildPhase
2845
{
305 dpurdie 2846
    my ($last) = @_;
2847
 
227 dpurdie 2848
    #
305 dpurdie 2849
    #   Ensure directive is allowed
2850
    #       $BUILDPHASE >  1     - No more directives allowed
2851
    #       $BUILDPHASE == 1     - Allowed directive
2852
    #
2853
    if ( $BUILDPHASE > 1 )
2854
    {
2855
        my $function = (caller(1))[3];
2856
        $function =~ s~.*::~~;
2857
        Error ("Directive not allowed: $function","'BuildMake' must be the last directive in the build file");
2858
    }
2859
 
2860
    #
227 dpurdie 2861
    #   Only do it once
2862
    #
305 dpurdie 2863
    return if ( $BUILDPHASE  );
2864
    $BUILDPHASE = 1;
227 dpurdie 2865
 
2866
    #
341 dpurdie 2867
    #   If we are not performing a ForceBuild, then we don't need to continue
2868
    #   We have updated the interface directory with BuildPkgArchive
2869
    #   information.
2870
    #
2871
    TestForForcedBuild();
2872
 
2873
    #
227 dpurdie 2874
    #   Calcuate the aliases that are being extracted from targets
2875
    #
2876
    Process_TargetAlias();
2877
 
2878
    #
4728 dpurdie 2879
    #   Calculate NATIVE alaias
2880
    #   Limit the Native Alias to active platforms
2881
    #
2882
    if (exists $BUILDALIAS{NATIVE})
2883
    {
2884
        Warning('User has manually specified a NATIVE alias','Default alias will not be set.');
2885
    }
2886
    else
2887
    {
2888
        my %activePatformMap = map {$_ => 1} @BUILD_ACTIVEPLATFORMS;
2889
        my @activeNatives;
2890
        foreach my $item (PlatformConfig::getNativeTargets())
2891
        {
2892
            push (@activeNatives, $item) if exists($activePatformMap{$item});
2893
        }
2894
 
2895
        $BUILDALIAS{NATIVE} = join(' ', @activeNatives);
2896
    }
2897
 
2898
    #
311 dpurdie 2899
    #   Create dummy package to describe the Interface directory
2900
    #
2901
    CreateInterfacePackage();
2902
 
2903
    #
227 dpurdie 2904
    #   Sanity test the users packages
2905
    #
2906
    PackageEntry::SanityTest() unless $Clobber;
2907
 
2908
    #
2909
    #   Validate the $Srcdir before its first real use
2910
    #   This is calculated from the user directives
2911
    #
2912
 
2913
    #.. Determine default "source" root
2914
    #
2915
    if ( $Srcdir eq "" )
2916
    {
2917
        Warning( "Both the directories 'src' and 'SRC' exist ....." )
2918
            if ( $ScmHost eq "Unix" && -e "src" && -e "SRC" );
2919
 
2920
        if ( -e "src" ) {
2921
            $Srcdir = "src";
2922
        } else {
2923
            ( -e "SRC" ) ||
2924
                Error( "Neither the directory 'src' nor 'SRC' exist ....." );
2925
            $Srcdir = "SRC";
2926
        }
2927
    }
2928
 
2929
    #
2930
    #   Must have a valid Srcdir
2931
    #
2932
    Error ("Source directory not found: $Srcdir")
2933
        unless ( $Srcdir && -d $Srcdir );
2934
 
305 dpurdie 2935
    #
2936
    #   Create source package
2937
    #
2938
    BuildSrcArchiveBody();
2939
 
227 dpurdie 2940
    return $Srcdir;
2941
}
2942
 
2943
#-------------------------------------------------------------------------------
341 dpurdie 2944
# Function        : TestForForcedBuild
2945
#
2946
# Description     : If a non-forced build has been requested, then see
2947
#                   if a build is required ( ie: build.pl modified )
2948
#
2949
#
2950
# Inputs          : None
2951
#
2952
# Returns         : May not return
2953
#
2954
sub TestForForcedBuild
2955
{
2956
    #
2957
    #   Always return if in clobber mode
2958
    #
2959
    return if ( $Clobber );
2960
 
2961
    if ( ! $ForceBuild  )
2962
    {
2963
        my @build_warn;
2964
        my $bstamp = -M "$Cwd/$ScmBuildSrc";
2965
        my $tstamp = -M "$Cwd/Makefile.gbe";
2966
 
2967
        push @build_warn, "Missing: Makefile.gbe" unless ( defined $tstamp );
2968
        push @build_warn, "Modified build file ($ScmBuildSrc)" if ( $tstamp && $bstamp < $tstamp );
2969
 
363 dpurdie 2970
        #
2971
        #   Ensure that the build filter has not changed
2972
        #   If the user has changed the buildfilter, then we need to
2973
        #   force a build.
2974
        #
2975
        #   The root Makefile.bge will have a $ScmBuildFilter entry
2976
        #
2977
        unless ( @build_warn )
2978
        {
2979
            use JatsMakeInfo;
2980
            ReadMakeInfo();
2981
                my $line = $::ScmBuildFilter || '';
2982
                $line =~ s~\s+~ ~g;
2983
 
2984
                my $filter = $::GBE_BUILDFILTER;
2985
                $filter =~ s~\s+~ ~g;
2986
                if ( $line ne $filter )
2987
                {
2988
                    push @build_warn, "Build filter has changed";
2989
                    Verbose2 ("Buildfilter Test: Was:$line, Is:$::GBE_BUILDFILTER");
2990
                }
2991
        }
2992
 
341 dpurdie 2993
        if ( @build_warn )
2994
        {
363 dpurdie 2995
            Verbose ("Forcing Build.", @build_warn );
341 dpurdie 2996
        }
2997
        else
2998
        {
2999
            Verbose ("No build performed. Build files up to date");
3000
            Log ("Build files up to date") if $::GBE_SANDBOX;
3001
            exit 0;
3002
        }
3003
    }
3004
}
3005
 
3006
#-------------------------------------------------------------------------------
305 dpurdie 3007
# Function        : LastBuildDirective
3008
#
3009
# Description     : No more build directives allowed
3010
#
3011
# Inputs          : 
3012
#
3013
# Returns         : 
3014
#
3015
sub LastBuildDirective
3016
{
3017
    $BUILDPHASE = 2;
3018
}
3019
 
3020
#-------------------------------------------------------------------------------
227 dpurdie 3021
# Function        : BuildPackageLink
3022
#
3023
# Description     : Create a soft link from sandbox_dpkg_archive to the package
3024
#                   being created by this build
3025
#
3026
#                   For backward compatability.
3027
#                   If GBE_DPKG_SBOX is not defined, then use GBE_DPKG_LOCAL
3028
#
3029
#                   This will allow multiple components to work together
3030
#
3031
#                   Note: When called in Clobber-mode the link will be deleted
3032
#
3033
# Inputs          : $BUILDNAME              - The package name
3034
#                   $BUILDNAME_PROJECT      - Project extension
3035
#                   $::GBE_DPKG_SBOX        - Path of sandbox_dpkg_archive
3036
#                   $::GBE_DPKG_LOCAL       - Path of local_dpkg_archive
3037
#                   $::GBE_DPKG             - Main repository
3038
#
3039
# Returns         : Nothing
3040
#
3041
sub BuildPackageLink
3042
{
3043
    my $target_archive;
3044
    my $target_archive_name;
3045
    my $link_file;
3046
    my $tag;
371 dpurdie 3047
    my $root_path;
227 dpurdie 3048
 
3049
    #
3050
    #   Determine the path (and name) of the target archive
3051
    #   Use sandbox_dpkg_archive if it exists
3052
    #   Use local_dpkg_acrhive for backward compatability (should be removed after JATS 2.64.2+)
3053
    #
3054
    if ( $target_archive = $::GBE_DPKG_SBOX )
3055
    {
3056
        $target_archive_name = "sandbox_dpkg_archive";
3057
        $tag = "Sandbox";
359 dpurdie 3058
        if ( $sandbox_exact )
3059
        {
3060
            $link_file = "$BUILDVERSION.lnk";
3061
        }
3062
        else
3063
        {
3064
            $link_file  = 'sandbox' . ${BUILDNAME_SUFFIX} . '.lnk';
3065
        }
371 dpurdie 3066
        $root_path = 'GBE_SANDBOX' . substr($Cwd, length($::GBE_SANDBOX));
3067
        Verbose2("Root Path: $::GBE_SANDBOX, $root_path");
227 dpurdie 3068
    }
3069
    elsif ( $target_archive = $::GBE_DPKG_LOCAL )
3070
    {
3071
        $target_archive_name = "local_dpkg_archive";
3072
        $link_file = "$BUILDVERSION.lnk";
3073
        $tag = "Local";
371 dpurdie 3074
        $root_path = $Cwd;
227 dpurdie 3075
    }
3076
    else
3077
    {
3078
        Verbose("Cannot locate local or sandbox archive")
3079
            unless $Clobber;
3080
        return;
3081
    }
3082
 
3083
    #
3084
    #   Santity test
3085
    #   Target must be a directory
3086
    #
3087
    unless ( -d $target_archive )
3088
    {
241 dpurdie 3089
        Warning("$target_archive_name is not a directory: $target_archive")
227 dpurdie 3090
            unless $Clobber;
3091
        return;
3092
    }
3093
 
3094
    my $link_dir = "$target_archive/$BUILDNAME_PACKAGE";
3095
    my $link_path = "$link_dir/$link_file";
3096
 
3097
    if ( $Clobber )
3098
    {
3099
        unlink $link_path;          # Delete the link
3100
        rmdir $link_dir;            # Delete only if empty
3101
    }
3102
    else
3103
    {
261 dpurdie 3104
        Log( "Local Link . $BUILDNAME_PACKAGE/$link_file ($tag)");
3105
        mkdir $link_dir unless -d $link_dir;
371 dpurdie 3106
        FileCreate ( $link_path, "$root_path/pkg/$BUILDNAME_PACKAGE");
227 dpurdie 3107
    }
3108
}
3109
 
3110
#-------------------------------------------------------------------------------
3111
# Function        : BuildSandboxData
3112
#
3113
# Description     : Create data structures to allow this package to be built
3114
#                   within a multi-package sandbox.
3115
#
3116
#                   This will allow multiple components to work together
3117
#
3118
#                   Note: When called in Clobber-mode the link will be deleted
3119
#
3120
# Inputs          : $BUILDNAME              - The package name
3121
#                   $BUILDNAME_PROJECT      - Project extension
3122
#                   $::GBE_DPKG_SBOX        - Path of sandbox_dpkg_archive
3123
#                   $::GBE_DPKG             - Main repository
3124
#
3125
# Returns         : Nothing
3126
#
3127
sub BuildSandboxData
3128
{
3129
    my $sandbox_dpkg_archive = $::GBE_DPKG_SBOX;
3130
    return unless ( $sandbox_dpkg_archive );
3131
 
3132
    unless ( -d $sandbox_dpkg_archive )
3133
    {
241 dpurdie 3134
        Error("sandbox_dpkg_archive is not a directory: $sandbox_dpkg_archive")
227 dpurdie 3135
            unless $Clobber;
3136
        return;
3137
    }
3138
 
3139
    #
3140
    #   Create a name for this package in the sandbox
3141
    #   Must use the package name and extension. Don't use the version
3142
    #   information as this will not be correct
3143
    #
3144
    #   PACKAGE/sandbox.PRJ.cfg
3145
    #
3146
    my $link_dir = "$sandbox_dpkg_archive/$BUILDNAME_PACKAGE";
359 dpurdie 3147
    my $link_file;
3148
 
3149
    if ( $sandbox_exact )
3150
    {
3151
        $link_file = "$BUILDVERSION.cfg";
3152
    }
3153
    else
3154
    {
3155
        $link_file  = 'sandbox' . ${BUILDNAME_SUFFIX} . '.cfg';
3156
    }
227 dpurdie 3157
    my $link_path = "$link_dir/$link_file";
3158
 
3159
    if ( $Clobber )
3160
    {
3161
        unlink $link_path;          # Delete the link
3162
        rmdir $link_dir;            # Delete only if empty
3163
    }
3164
    else
3165
    {
261 dpurdie 3166
        Log( "Sandbox cfg. $link_file");
227 dpurdie 3167
        unlink $link_path;
3168
        mkdir $link_dir;
3169
 
3170
        #
3171
        #   Create the sandbox config data structure
3172
        #
3173
        my %sandbox_info = (
3174
            BUILDDIR     => $Cwd,
3175
            INTERFACEDIR => $BUILDINTERFACE,
3176
            );
3177
 
3178
        #
3179
        #   Write out the Parsed Config File with new information
3180
        #
3181
        my $fh = ConfigurationFile::New( $link_path );
3182
        $fh->Header( "buildlib (version $::BuildVersion)",
3183
                                  "Sandbox configuration" );
3184
 
3185
        #
3186
        #   Dump out the configuration information
3187
        #
3188
        $fh->Dump( [\%sandbox_info], [qw(*sandbox_info)] );
3189
        $fh->Close();
3190
    }
3191
}
3192
 
3193
 
3194
#-------------------------------------------------------------------------------
3195
# Function        : BuildMake
3196
#
3197
# Description     : Generate the makefiles
3198
#                   This directive MUST be the last directive in the build.pl
3199
#                   file. The directive triggers the processing of all the
3200
#                   information that has been collected
3201
#
3202
#
3203
# Inputs          : None
3204
#
3205
# Returns         : Nothing
3206
#
3207
 
3208
sub BuildMake
3209
{
3210
    my( $argc, $platform );
3211
 
3212
    #
3213
    #   Must have a valid $BUILDINTERFACE
3214
    #   Normally this is held in the interface directory, but this is not
3215
    #   always created. If there is no $BUILDINTERFACE, then use the
3216
    #   build directory
3217
    #
3218
    $BUILDINTERFACE = "." unless ( $BUILDINTERFACE );
3219
 
3220
    #.. Starting the build phase. No more data collection
3221
    #
305 dpurdie 3222
    StartBuildPhase();
3223
    LastBuildDirective();
227 dpurdie 3224
 
5109 dpurdie 3225
    #
3226
    #   Now that the bulk of the information has been displayed
3227
    #   we can display captured messages. These warnings will be 
3228
    #   at the end of the log so that users can see them.
3229
    DumpCapture();
3230
 
227 dpurdie 3231
    sub DeleteCfg
3232
    {
3233
        #
3234
        #   Delete files that will be re-created
3235
        #   Some of these files are read and written.
3236
        #   Errors in the files are solved by deleting the files now.
3237
        #
3238
        unlink "$BUILDINTERFACE/build.cfg";
3239
        unlink "$BUILDINTERFACE/Makefile.cfg";
3240
        unlink glob ("$BUILDINTERFACE/Makefile*.cfg");
3241
        unlink "$BUILDINTERFACE/Buildfile.cfg";
3242
        unlink "$BUILDINTERFACE/Dpackage.cfg";
3243
    }
3244
 
3245
    if ( $Clobber )                             # clobber mode ?
3246
    {
4003 dpurdie 3247
        #
3248
        #   Read in toolset files - a list of files collected during
3249
        #   previous builds
3250
        #
3251
        ToolsetFile();
227 dpurdie 3252
 
4003 dpurdie 3253
        #
3254
        #   Unmake all the makefiles
3255
        #   No longer needed as we track the file that are created
3256
        #
3257
        #if ( -e "Makefile.gbe" )
3258
        #{
3259
        #    JatsTool ( 'jmake.pl', 'unmakefiles');
3260
        #}
3261
 
3262
        #
3263
        #   Delete my own configuration files
3264
        #
227 dpurdie 3265
        DeleteCfg();
3266
 
3267
        #
3268
        #   JATS creates a 'pkg' directory for the target package
3269
        #
3270
        push @CLOBBERDIRS, "pkg";
3271
 
3272
        #
3273
        #   Deployment creates a 'build/deploy' directory
375 dpurdie 3274
        #   The 'build' directory may contain user files - only remove if empty
227 dpurdie 3275
        #
3276
        push @CLOBBERDIRS, "build/deploy";
375 dpurdie 3277
        push @REMOVEDIRS, "build";
227 dpurdie 3278
 
3279
        #
3280
        #   Delete interface directories and other directories that have been
375 dpurdie 3281
        #   marked to be clobbered
227 dpurdie 3282
        #
3283
        foreach my $dir ( @CLOBBERDIRS )
3284
        {
3285
            next if ( $dir eq '.' );
3286
            next if ( $dir eq '..' );
3287
            if ( -d $dir )
3288
            {
361 dpurdie 3289
                RmDirTree ( $dir );
227 dpurdie 3290
            }
3291
        }
3292
 
375 dpurdie 3293
        foreach my $dir ( @REMOVEDIRS )
3294
        {
3295
            next if ( $dir eq '.' );
3296
            next if ( $dir eq '..' );
3297
            if ( -d $dir )
3298
            {
3299
                rmdir ( $dir ); # Only if empty
3300
            }
3301
        }
3302
 
4003 dpurdie 3303
        if ( exists $::GBE_TOOLSETFiles{Files} )
227 dpurdie 3304
        {
4007 dpurdie 3305
            foreach my $file (keys %{$::GBE_TOOLSETFiles{Files}})
227 dpurdie 3306
            {
4003 dpurdie 3307
                if ( -f $file )
3308
                {
3309
                    RmDirTree ( $file );
3310
                }
227 dpurdie 3311
            }
3312
        }
3313
 
3314
        #
3315
        #   DPACKAGE may be a user file, Only delete it if we created it
3316
        #
299 dpurdie 3317
        unlink "$Srcdir/DPACKAGE.$::GBE_MACHTYPE" if $DeleteDPACKAGE;
227 dpurdie 3318
 
3319
        BuildPackageLink();
3320
        BuildSandboxData();
3321
        return;
3322
    }
3323
 
3324
    #.. Build support files
3325
    #
3326
    DeleteCfg();
3327
    BuildConfig();
3328
    BuildSharedLibFiles();
3329
    WriteParsedBuildConfig();
3330
    BuildPackageLink();
3331
    BuildSandboxData();
4003 dpurdie 3332
    NoBuildMarker();
227 dpurdie 3333
 
3334
    #
3335
    #  ONLY (re)building interface dir
3336
    #
3337
    return
3338
        if ( $Interface );
3339
 
3340
    #---------------------------------------------------------------------------
3341
    #
3342
    #.. Make bootstrap "makefile",
3343
    #   Simulate a top level makefile
3344
    #       Pass argumenst to makelib
3345
    #       Sumulate SubDir() operations
3346
    #       Sumulate a Platform(*);
3347
    #
3348
    #       Due to the normal way that makelib.pl is executed,
3349
    #       the following substitutions are done.
3350
    #
3351
    @ARGV = ();
3352
    $0 = "makefile.pl ";
3353
    push @ARGV, "$Cwd";                         # current working directory
331 dpurdie 3354
    push @ARGV, "$::GBE_TOOLS/makelib.pl";     # makelib.pl image
227 dpurdie 3355
    push @ARGV, "--interface=$BUILDINTERFACE"
261 dpurdie 3356
        if ($BUILDINTERFACE);
227 dpurdie 3357
 
3358
    Debug( "ARGV:      @ARGV" );
3359
 
3360
    #.. (re)Build root makefile
3361
    #
3362
    $ScmBuildlib = 0;                           # clear Buildlib flag for 'makelib.pl'
3363
    RootMakefile();                             # inform 'makelib.pl'
3364
    MakeLibInit();                              # run initialisation
3365
 
3366
    #.. Register subdir(s)
3367
    #
3368
    UniquePush (\@BUILDSUBDIRS, $Srcdir );
3369
    SubDir( @BUILDSUBDIRS );
3370
    Platform( @BUILD_ACTIVEPLATFORMS );
3371
 
3372
    #.. (re)build src makefiles and associated information
367 dpurdie 3373
    #   JatsTool will not return on error
227 dpurdie 3374
    #
263 dpurdie 3375
    my @cmds = ('jmake.pl', 'rebuild');
227 dpurdie 3376
    push @cmds, 'NORECURSE=1' if ( $RootOnly );
263 dpurdie 3377
    JatsTool ( @cmds);
305 dpurdie 3378
 
3379
    #
3380
    #   Generate some warnings that will be seen at the end of the build
3381
    #
3382
    Warning ("BuildSrcArchive Directive Present","Read JATS Manual for correct usage")
3383
        if ($build_source_pkg);
227 dpurdie 3384
}
3385
 
3386
 
3387
#-------------------------------------------------------------------------------
3388
# Function        : BuildVersion
3389
#
3390
# Description     : Generate version.c and version.h files
3391
#
3392
# Inputs          : Options
3393
#                       --Prefix=prefix         Text prepended to variables created
3394
#                                               as a part of the "C" versions
3395
#                       --Type=type             Type of "C" style data
3396
#                                               Allowed types are: array
3397
#                       --Defs=name             Generate a "C" definitions file.
3398
#                                               This file simply contains definitions
3399
#                       --Defs                  Same as --Defs=defs
3400
#                       --Style=style           Output file style
3401
#                                               Supported styles:
3402
#                                                   "C" - Default
3403
#                                                   "CSharp"
3404
#                                                   "WinRC"
289 dpurdie 3405
#                                                   "Delphi"
315 dpurdie 3406
#                                                   "VB"
227 dpurdie 3407
#                       --File=name             Specifies the output file name
3408
#                                               Default is determined by the style
3409
#
3410
#                   Also allows for an 'old' style format in which
3411
#                   the first three arguments are prefix,type and defs
3412
# Returns         :
3413
#
3414
 
3415
sub BuildVersion
3416
{
3417
    my ( $Prefix, $Type, $Mode ) = @_;
3418
    my $ModePrefix;
3419
    my $Style = "C";
3420
    my $FileName;
3421
    my $VersionFiles;
267 dpurdie 3422
    my @opts;
3423
    my $supports_opts;
227 dpurdie 3424
 
3425
    StartBuildPhase();                          # Starting the build phase. No more data collection
3426
 
279 dpurdie 3427
    if ( defined($Prefix) && $Prefix =~ /^-/ )
227 dpurdie 3428
    {
3429
        $Prefix = undef;
3430
        $Type = undef;
3431
        $Mode = undef;
3432
        foreach  ( @_ )
3433
        {
3434
            if (      /^--Prefix=(.*)/ ) {
3435
                $Prefix = $1;
3436
                $VersionFiles = 1;
3437
 
3438
            } elsif ( /^--Type=(.*)/ ) {
3439
                $Type = $1;
3440
                $VersionFiles = 1;
3441
 
3442
            } elsif ( /^--Defs=(.*)/ ) {
3443
                $Mode = $1;
3444
                $ModePrefix = "_$1";
3445
 
3446
            } elsif ( /^--Defs$/ ) {
3447
                $Mode = 'defs';
3448
                $ModePrefix = "";
3449
 
3450
            } elsif ( /^--Style=(.*)/ ) {
3451
                $Style = $1;
279 dpurdie 3452
                $VersionFiles = 1;
267 dpurdie 3453
                $supports_opts = 1 if ( $Style =~ /^WinRC/i );
227 dpurdie 3454
 
3455
            } elsif ( /^--File=(.*)/ ) {
3456
                $FileName = $1;
3457
 
267 dpurdie 3458
            } elsif ($supports_opts ) {
3459
                push @opts, $_;
235 dpurdie 3460
 
227 dpurdie 3461
            } else {
3462
                Error ("BuildVersion: Unknown option: $_");
3463
 
3464
            }
3465
        }
3466
    }
3467
    else
3468
    {
3469
        #
3470
        #   Old style positional arguments.
3471
        #
3472
        $VersionFiles = 1;
3473
        if ( defined( $Mode ) )
3474
        {
3475
            if ( $Mode =~ m/^defs(=(.*))?$/i )
3476
            {
3477
                $Mode       = $2 ? $2    : 'defs';
3478
                $ModePrefix = $2 ? "_$2" : "";
3479
            }
3480
            else
3481
            {
3482
                Error ("BuildVersion: Bad Mode argument. Need 'defs' or 'defs=name'");
3483
            }
3484
        }
3485
    }
3486
 
3487
    #
3488
    #   Determine the style of version file to create
3489
    #
3490
    if ( $Style =~ /^CSharp/i ) {
3491
        BuildVersionCSharp( $FileName );
3492
 
229 dpurdie 3493
    } elsif ( $Style =~ /^Properties/i ) {
3494
        BuildVersionProperties( $FileName, $Prefix );
3495
 
227 dpurdie 3496
    } elsif ( $Style =~ /^WinRC/i ) {
267 dpurdie 3497
        BuildVersionWinRC( $FileName, @opts );
227 dpurdie 3498
 
289 dpurdie 3499
    } elsif ( $Style =~ /^Delphi/i ) {
3500
        BuildVersionDelphi( $FileName, $Prefix );
315 dpurdie 3501
 
3502
    } elsif ( $Style =~ /^VB/i ) {
3503
        BuildVersionVB( $FileName, $Prefix );
289 dpurdie 3504
 
227 dpurdie 3505
    } elsif ( $Style eq "C" ) {
289 dpurdie 3506
        BuildVersionC    ( $FileName, $Prefix, $Type )     if ( $VersionFiles );
3507
        BuildVersionCdefs( $FileName, $Mode, $ModePrefix ) if ( $Mode );
227 dpurdie 3508
 
3509
    } else {
3510
        Error("BuildVersion: Unknown style: $Style");
3511
    }
3512
}
3513
 
3514
#-------------------------------------------------------------------------------
3515
# Function        : BuildDescpkg
3516
#
3517
# Description     : Create a package description file
3518
#                   The format of this file matches that generated by JANTS
3519
#                   Take care when extending the format
3520
#
3521
#                   NOTE: It turns out that JANTS is not a standard and the
3522
#                         implementors (of JANTS) kept on changing it.
3523
#
3524
# Inputs          :
3525
#
3526
# Returns         :
3527
#
3528
sub BuildDescpkg
3529
{
4003 dpurdie 3530
    StartBuildPhase();                      # Starting the build phase. No more data collection
3531
    return if ( $Clobber );                 # clobber mode ?
227 dpurdie 3532
 
247 dpurdie 3533
    #
3534
    #   Store the files location for use at runtime
3535
    #   It will be a file that is 'known' to JATS
3536
    #
4003 dpurdie 3537
    my $pkgfile = BuildAddKnownFile ( $NoBuild ? $Cwd : $Srcdir, 'descpkg' );
227 dpurdie 3538
 
261 dpurdie 3539
    my @desc;
279 dpurdie 3540
    push @desc, "Package Name:  $BUILDNAME_PACKAGE";
3541
    push @desc, "Version:       $BUILDVERSION";
3542
    push @desc, "Released By:   $::USER";
3543
    push @desc, "Released On:   $::CurrentTime";
3544
    push @desc, "Build Machine: $::GBE_HOSTNAME";
3545
    push @desc, "Path:          $Cwd";
3546
    push @desc, "Jats Version:  $::GBE_VERSION";
3547
    push @desc, "Jats Path:     $::GBE_CORE";
261 dpurdie 3548
    push @desc, "";
3549
    push @desc, "Build Dependencies:";
3550
    push @desc, "";
227 dpurdie 3551
 
3552
    foreach my $tag ( PackageEntry::GetPackageList )
3553
    {
3554
        my ($name, $version, $type) = PackageEntry::GetPackageData($tag);
3555
 
3556
        my @attributes;
3557
 
3558
        push @attributes, "name=\"$name\"";
3559
        push @attributes, "version=\"$version\"";
3560
        push @attributes, "build=\"true\"" if $type =~ /Build/i;
3561
 
261 dpurdie 3562
        push @desc, "<sandbox @attributes/>";
227 dpurdie 3563
    }
247 dpurdie 3564
 
261 dpurdie 3565
    FileCreate ($pkgfile, \@desc );
227 dpurdie 3566
}
3567
 
3568
#-------------------------------------------------------------------------------
4003 dpurdie 3569
# Function        : NoBuildMarker
3570
#
3571
# Description     : Maintain the nobuild marker
3572
#                   This is file placed in the interface directory simply
3573
#                   to indicate to the 'create_dpkg' utility that this build
3574
#                   does not do anything useful.
3575
#
3576
#                   It will only be used on a build machine by the buid daemon
3577
#
3578
#                   Its not placed in the interface directory as it would be
3579
#                   harder for create_dpkg to find it.
3580
#
3581
# Inputs          : None
3582
# Globals         : $NoBuild, $Clobber
3583
#
3584
# Returns         : Nothing
3585
#
3586
sub NoBuildMarker
3587
{
3588
    return if ( $Clobber );
3589
 
3590
    # Always delete the file - in case we toggle build forms
3591
    #
3592
    my $markerFile = BuildAddKnownFile( $Cwd, 'noBuild.gbe');
3593
    unlink($markerFile);
3594
 
3595
    TouchFile($markerFile)
3596
        if ($NoBuild);
3597
}
3598
 
3599
#-------------------------------------------------------------------------------
227 dpurdie 3600
# Function        : BuildIncpkg
3601
#
3602
# Description     : Create a package inclusion file
3603
#
3604
# Inputs          :
3605
#
3606
# Returns         :
3607
#
3608
sub BuildIncpkg
3609
{
3610
    StartBuildPhase();                          # Starting the build phase. No more data collection
3611
    if ( $Clobber )                             # clobber mode ?
3612
    {
361 dpurdie 3613
        RmDirTree( "$Srcdir/incpkg" );
227 dpurdie 3614
        return;
3615
    }
3616
 
3617
    my $fh = ConfigurationFile::New( "$Srcdir/incpkg" );
3618
    $fh->Header( "buildlib (Version $BuildVersion)",
3619
                              "Package inclusion list" );
3620
 
3621
    foreach my $tag ( PackageEntry::GetPackageList )
3622
    {
3623
        my ($name, $version, $type) = PackageEntry::GetPackageData($tag);
3624
        $type = ($type =~ /build/i) ? "Build" : "Link";
3625
 
3626
        $fh->Write( "${type}PkgArchive( '$name', '$version' );\n" );
3627
    }
3628
 
3629
    $fh->Close();
3630
}
3631
 
3632
#-------------------------------------------------------------------------------
3633
# Function        : BuildConfig
3634
#
3635
# Description     : Create the file interface/build.cfg
3636
#                   This file contains information gathered by the build process
3637
#                   that is to be used when makefiles are created and re-created
3638
#
3639
# Inputs          : None
3640
#
3641
# Returns         : Nothing
3642
#
283 dpurdie 3643
sub BuildConfig
227 dpurdie 3644
{
3645
    Error( "No BuildInterface directive encountered\n" )
3646
        unless ($BUILDINTERFACE);
3647
 
3648
    my $fh = ConfigurationFile::New( "$BUILDINTERFACE/build.cfg");
3649
    $fh->Header( "buildlib (Version $BuildVersion)",
3650
                              "Makelib configuration file", "
3651
\$ScmBuildMachType              = \"$::GBE_MACHTYPE\";
3652
\$ScmInterfaceVersion           = \"$::InterfaceVersion\";
3653
\$ScmBuildName                  = \"$BUILDNAME\";
3654
\$ScmBuildPackage               = \"$BUILDNAME_PACKAGE\";
3655
\$ScmBuildVersion               = \"$BUILDNAME_VERSION\";
3656
\$ScmBuildProject               = \"$BUILDNAME_PROJECT\";
3657
\$ScmBuildVersionFull           = \"$BUILDVERSION\";
3658
\$ScmBuildPreviousVersion       = \"$BUILDPREVIOUSVERSION\";
3659
\$ScmLocal                      = \"$BUILDLOCAL\";
3660
\$ScmDeploymentPatch            = \"$DEPLOY_PATCH\";
3661
\$ScmSrcDir                     = \"$Srcdir\";
3662
\$ScmBuildSrc                   = \"$ScmBuildSrc\";
3663
\$ScmExpert                     = \"$Expert\";
261 dpurdie 3664
\$ScmAll                        = \"$All\";
4003 dpurdie 3665
\$ScmNoBuild                    = \"$NoBuild\";
227 dpurdie 3666
");
3667
 
3668
#.. Alias
3669
#
3670
    $fh->DumpData(
3671
        "\n# Aliases.\n#\n",
3672
        "ScmBuildAliases", \%BUILDALIAS );
3673
 
3674
#.. Products
3675
#
3676
    $fh->DumpData(
3677
        "# Product mapping.\n#\n",
3678
        "ScmBuildProducts", \%BUILDPRODUCT_PARTS );
3679
 
3680
#.. Create ScmBuildPlatforms
3681
#
3682
    my( @platforms_merged, %platform_args ) = ();
3683
 
3684
    UniquePush ( \@platforms_merged, @BUILDPLATFORMS );
3685
 
3686
    foreach my $key ( keys %BUILDPRODUCT ) {
3687
        my( @list ) = split( ' ', $BUILDALIAS{ $key } || '' );
3688
        my( $platform );
3689
 
3690
        foreach my $elem ( @list ) {
3691
            if ( $elem =~ /^--/ ) {             # argument
3692
                HashJoin( \%platform_args, $;, $platform, $elem )
3693
                    if ( defined($platform) );
3694
                next;
3695
            }
3696
            $platform = $elem;                  # platform
3697
            UniquePush( \@platforms_merged, $elem );
3698
        }
3699
    }
3700
 
3701
#.. Create ScmBuildPlatforms
3702
#   Contains per platform options extracted from alias and platform args
3703
#
3704
    my %ScmBuildPlatforms;
3705
    foreach my $key ( @platforms_merged ) {
3706
 
3707
        my( @arguments ) = ();
3708
        UniquePush( \@arguments, split( /$;/, $BUILDPLATFORMARGS{ $key } ))
3709
            if ( exists $BUILDPLATFORMARGS{ $key } );
3710
 
3711
        UniquePush( \@arguments, split( /$;/, $platform_args{ $key } ))
3712
            if ( exists $platform_args{ $key } );
3713
 
3714
        $ScmBuildPlatforms{$key} = join "$;", @arguments;
3715
    }
3716
 
3717
    $fh->DumpData(
3718
        "# Platform and global argument list.\n#\n",
3719
        "ScmBuildPlatforms", \%ScmBuildPlatforms );
3720
 
3721
 
3722
# .. Create BuildPkgRules
3723
#
367 dpurdie 3724
#    This is most of the information contained within %PKGRULES, which
227 dpurdie 3725
#    requires additional processing within makelib.
3726
#
367 dpurdie 3727
#   Need the True Path for windows.
3728
#       Some makefile functions (wildcard) only work as expected
3729
#       if the case of the pathname is correct. Really only a problem
3730
#       with badly formed legecy packages where the Windows user
3731
#       guessed at the package format.
3732
#
227 dpurdie 3733
    my %ScmBuildPkgRules;
3734
    foreach my $platform ( keys %PKGRULES )
3735
    {
3736
        foreach my $package ( @{$PKGRULES{$platform}} )
3737
        {
3738
            my %entry;
3739
 
367 dpurdie 3740
            $entry{ROOT}     = TruePath( $package->{'base'} );
227 dpurdie 3741
            $entry{NAME}     = $package->{'name'};
3742
            $entry{VERSION}  = $package->{'version'};
3743
            $entry{DNAME}    = $package->{'dname'};
3744
            $entry{DVERSION} = $package->{'dversion'};
3745
            $entry{DPROJ}    = $package->{'dproj'};
3746
            $entry{TYPE}     = $package->{'type'};
3747
            $entry{CFGDIR}   = $package->{'cfgdir'} if ( defined( $package->{'cfgdir'} ) );
3748
 
367 dpurdie 3749
            foreach my $dir (qw (TOOLDIRS) )
227 dpurdie 3750
            {
3751
                $entry{$dir} = $package->{$dir} ;
3752
            }
3753
 
367 dpurdie 3754
            my $baselen = length($package->{'base'});
3755
            foreach my $dir (qw (PINCDIRS PLIBDIRS THXDIRS) )
3756
            {
3757
                $entry{$dir} = [];
3758
                foreach my $file ( @{$package->{$dir}} )
3759
                {
3760
                    push @{$entry{$dir}}, substr TruePath($package->{'base'} . $file ), $baselen;
3761
                }
3762
            }
3763
 
227 dpurdie 3764
            push @{$ScmBuildPkgRules{$platform}}, \%entry;
3765
        }
3766
    }
3767
 
3768
    $fh->DumpData(
3769
        "# Imported packages.\n#\n",
3770
        "ScmBuildPkgRules", \%ScmBuildPkgRules );
3771
 
3772
#
3773
#   BUILDPLATFORMS,
3774
#       The value that is saved only contains the active platforms
3775
#
3776
#   DEFBUILDPLATFORMS,
3777
#       The value that is matchs the wildcard specification for Platform 
3778
#       directives.
3779
#
3780
    $fh->DumpData(
3781
        "# A list of platforms active within the view.\n#\n",
3782
        "BUILDPLATFORMS", \@BUILD_ACTIVEPLATFORMS );
3783
 
3784
    $fh->DumpData(
3785
        "# A list of default platforms within the view.\n#\n",
3786
        "DEFBUILDPLATFORMS", \@DEFBUILDPLATFORMS );
3787
 
3788
#
3789
#   BUILDTOOLS
3790
#       A list of toolset extension paths
3791
#
3792
    $fh->DumpData(
3793
        "# A list of paths with toolset extension programs.\n#\n",
3794
        "BUILDTOOLSPATH", \@BUILDTOOLS );
3795
 
3796
#
3797
#   BUILDPLATFORM_PARTS
3798
#       A subset of BUILDINFO exported as BUILDPLATFORM_PARTS
3799
#       This exists only for backward compatability with existing code
3800
#       in external packages ( deployfiles).
3801
#
3802
#   Only save those parts that are part of the current build
3803
#   This will prevent users attempting to build for platforms that have not
3804
#   been correctly constructed.
3805
#
3806
    my %active =  map { ${_} => 1 } @BUILD_ACTIVEPLATFORMS;
3807
    my %active_buildplatform_parts;
3808
    my %active_build_info;
3809
    foreach ( keys %BUILDINFO )
3810
    {
3811
        next unless ( $active{$_} );
3812
        $active_buildplatform_parts{$_} = $BUILDINFO{$_}{PARTS};
3813
        $active_build_info{$_}          = $BUILDINFO{$_};
3814
    }
3815
 
3816
    $fh->DumpData(
3817
        "# Parts of all platforms.\n#\n",
3818
        "BUILDPLATFORM_PARTS", \%active_buildplatform_parts );
3819
#
3820
#   BUILDINFO
3821
#       Complete TARGET Information
3822
#
3823
    $fh->DumpData(
3824
        "# Extended build information.\n#\n",
3825
        "BUILDINFO", \%active_build_info );
3826
 
3827
#
247 dpurdie 3828
#   BUILD_KNOWNFILES
3829
#       All paths are relative to the project root directory
3830
#       ie: The directory that conatins the build.pl file
3831
#
3832
    $fh->DumpData(
3833
        "# Generated Files that may be known when used as Src files.\n#\n",
3834
        "BUILD_KNOWNFILES", \%BUILD_KNOWNFILES );
3835
 
3836
#
227 dpurdie 3837
#   Close out the file
3838
#
3839
    $fh->Close();
363 dpurdie 3840
 
227 dpurdie 3841
}
3842
 
3843
#-------------------------------------------------------------------------------
3844
# Function        : WriteParsedBuildConfig
3845
#
3846
# Description     : Write all the parsed build.pl data to a single file
3847
#                   Its all in there for use
3848
#
3849
# Inputs          : 
3850
#
3851
# Returns         : 
3852
#
3853
sub WriteParsedBuildConfig
3854
{
3855
    my $cfg_file = "$::BUILDINTERFACE/Buildfile.cfg";
3856
    my %cf_build_info = ();
3857
 
3858
    #
3859
    #   Examine the symbol table and capture most of the entries
3860
    #
3861
    foreach my $symname (keys %main::)
3862
    {
3863
        next if ( $symname =~ m/::/  );                 # No Typeglobs
3864
        next if ( $symname =~ m/^cf_build_info/  );     # Not myself
3865
        next unless ( $symname =~ m/^[A-Za-z]/  );      # No system type names
3866
        next if ( $symname =~ m/^SIG$/  );              # Useless
3867
        next if ( $symname =~ m/^ENV$/  );              # Don't keep the user ENV
3868
        next if ( $symname =~ m/^INC$/  );              # Don't keep the INC paths
3869
        next if ( $symname =~ m/^DEFINES/  );           # Don't keep
3870
        next if ( $symname =~ m/^TOOLSETRULES/  );      # Don't keep
3871
 
331 dpurdie 3872
        no strict 'vars';
227 dpurdie 3873
        local *sym = $main::{$symname};
3874
 
331 dpurdie 3875
        $cf_build_info{"\$$symname"} =  $sym if defined $sym;
369 dpurdie 3876
        $cf_build_info{"\@$symname"} = \@sym if @sym;
3877
        $cf_build_info{"\%$symname"} = \%sym if %sym;
331 dpurdie 3878
        use strict 'vars';
227 dpurdie 3879
    }
3880
 
3881
    #
3882
    #   Dump out the configuration information
3883
    #
3884
    my $fh = ConfigurationFile::New( "$cfg_file" );
3885
    $fh->Header( "buildlib (version $::BuildVersion)",
3886
                              "Buildfile configuration" );
3887
    $fh->Dump( [\%cf_build_info], [qw(*cf_build_info)] );
3888
    $fh->Close();
3889
}
3890
 
3891
 
3892
#-------------------------------------------------------------------------------
3893
# Function        : BuildSharedLibFiles
3894
#
3895
# Description     : Create a file in the interface directory that will specify
3896
#                   the locations of shared libraries.
3897
#
3898
#                   Note: Always create a file as makefile targets depend on it.
3899
#
3900
#                   This is a bit ugly.
3901
#
3902
#                   There needs be an association between the build machine and
3903
#                   the target platform. Need to know if the current target is
3904
#                   native to the current build machine. If it is then we can
3905
#                   run tests on the machine and we then need to extend the
3906
#                   search path for the target.
3907
#
3908
#                   The BUILDINFO{EXT_SHARED} is used to control the creation of
3909
#                   the files by specifying the extension of the file.
3910
#
3911
# Inputs          : None
3912
#
3913
# Returns         :
3914
#
3915
sub BuildSharedLibFiles
3916
{
3917
    if ( $ScmHost eq "DOS" || $ScmHost eq "WIN" ) {
3918
        BuildSharedLibFiles_WIN(@_);
3919
 
3920
    } elsif ( $ScmHost eq "Unix" ) {
3921
        BuildSharedLibFiles_Unix(@_);
3922
 
3923
    } else {
3924
        Error("Cannot build. Unknown machine type: $ScmHost",
3925
              "Need WIN, DOS or Unix" );
3926
    }
3927
}
3928
 
3929
#-------------------------------------------------------------------------------
3930
# Function        : BuildSharedLibFiles_WIN
3931
#
3932
# Description     : Implementation of BuildSharedLibFiles for Windows
3933
#
3934
# Inputs          : None
3935
#
3936
sub BuildSharedLibFiles_WIN
3937
{
3938
 
3939
    foreach my $platform ( @BUILD_ACTIVEPLATFORMS )
3940
    {
3941
        next unless ( exists $BUILDINFO{$platform}{EXT_SHARED} );
3942
        my @dos_paths = BuildSharedLibFiles_list( $platform, $BUILDINFO{$platform}{EXT_SHARED} );
3943
 
3944
        #
3945
        #   Create a .bat file for WIN32
3946
        #   This may be consumed by user wrapper programs
3947
        #
229 dpurdie 3948
        #   Features: No Echo
3949
        #             Use of SETLOCAL to prevent pollution of environment
3950
        #
227 dpurdie 3951
        my $fh = ::ConfigurationFile::New( "$BUILDINTERFACE/set_$platform.bat", '--NoEof', '--Type=bat' );
229 dpurdie 3952
        $fh->Write ( "\@echo off\n");
227 dpurdie 3953
        $fh->Header( "Buildlib ($BuildVersion)","Shared Library Paths" );
229 dpurdie 3954
        $fh->Write ( "\nSETLOCAL\n");
227 dpurdie 3955
        foreach ( reverse @dos_paths )
3956
        {
3957
            $_ =~ s~/~\\~g;
3958
            $fh->Write ( "PATH=$_;\%PATH\%\n" );
3959
        }
3960
        $fh->Write ( "\n%*\n" );
229 dpurdie 3961
        $fh->Write ( "\nENDLOCAL\n");
231 dpurdie 3962
        $fh->Write ( "EXIT /B %ERRORLEVEL%\n");
227 dpurdie 3963
        $fh->Close();
3964
 
3965
        #
3966
        #   Create a .sh file for WIN32
3967
        #   This may be consumed by a shell - as used within JATS
3968
        #
3969
        $fh = ::ConfigurationFile::New( "$BUILDINTERFACE/set_$platform.sh", '--NoEof', '--Type=sh' );
3970
        $fh->Header( "Buildlib ($BuildVersion)","Shared Library Paths" );
3971
        foreach ( reverse @dos_paths )
3972
        {
3973
            tr~\\/~/~s;
3974
            $fh->Write ( "PATH=$_\\;\$PATH\n" );
3975
        }
287 dpurdie 3976
        $fh->Write ( "\n" . '[ -n "$*" ] && "$@"'  ."\n" );
227 dpurdie 3977
        $fh->Close();
3978
    }
3979
}
3980
 
3981
#-------------------------------------------------------------------------------
3982
# Function        : BuildSharedLibFiles_Unix
3983
#
3984
# Description     : Implementation of BuildSharedLibFiles for Unix
3985
#                   Extend the Shared Library search path via LD_LIBRARY_PATH
3986
#
3987
# Inputs          : None
3988
#
3989
sub BuildSharedLibFiles_Unix
3990
{
3991
    foreach my $platform ( @BUILD_ACTIVEPLATFORMS )
3992
    {
3993
        next unless ( exists $BUILDINFO{$platform}{EXT_SHARED} );
3994
        my @unix_paths = BuildSharedLibFiles_list( $platform, $BUILDINFO{$platform}{EXT_SHARED} );
3995
 
3996
        #
3997
        #   Create a .sh file for Unix
3998
        #
229 dpurdie 3999
        my $file = "$BUILDINTERFACE/set_$platform.sh";
4000
        my $fh = ::ConfigurationFile::New( $file , '--NoEof', '--Type=sh' );
227 dpurdie 4001
        $fh->Header( "Buildlib ($BuildVersion)","Shared Library Paths" );
4002
        foreach ( reverse @unix_paths )
4003
        {
4004
            $fh->Write ( "export LD_LIBRARY_PATH=$_:\$LD_LIBRARY_PATH\n" );
4005
        }
275 dpurdie 4006
        $fh->Write ( "\n\"\$\@\"\n" );
227 dpurdie 4007
        $fh->Close();
229 dpurdie 4008
 
4009
        #
4010
        #   Make the file executable under unix
4011
        #
4012
        chmod 0755, $file;
227 dpurdie 4013
    }
4014
}
4015
 
4016
#-------------------------------------------------------------------------------
4017
# Function        : BuildSharedLibFiles_list
4018
#
4019
# Description     : Determine a list of Shared Library paths that can be used
4020
#                   by the current target
4021
#
4022
# Inputs          : $platform       - Current platform
4023
#                   $so             - Shared object extensions
4024
#
4025
# Returns         : List of search paths
4026
#
4027
sub BuildSharedLibFiles_list
4028
{
4029
    my ($platform, $so ) = @_;
4030
    my @paths;
4031
    my @parts = @{$BUILDINFO{$platform}{PARTS}};
4032
 
4033
    #
4034
    #   Paths from the current build
4035
    #       Local directory         - for installed components
4036
    #       Interface directory     - for BuildPkgArchives
4037
    #
4038
    if ( $BUILDLOCAL )
4039
    {
4040
        foreach ( @parts )
4041
        {
4042
            push @paths, AbsPath("$BUILDLOCAL/lib/$_");
4043
        }
4044
    }
4045
 
4046
    foreach ( @parts )
4047
    {
4048
            push @paths, AbsPath("$BUILDINTERFACE/lib/$_");
4049
    }
4050
 
4051
    #
4052
    #   For each LinkPkgArchive
4053
    #
4054
    foreach my $package ( @{$PKGRULES{$platform}} )
4055
    {
4056
        next unless ( $package->{'type'} eq 'link' );
4057
 
4058
        my $base = $package->{'base'};
4059
        for my $path ( @{$package->{'PLIBDIRS'}} )
4060
        {
289 dpurdie 4061
            my @so_libs;
317 dpurdie 4062
            push @so_libs, glob ( "$base$path/*$_") foreach ( ArrayList($so) );
227 dpurdie 4063
            next unless scalar @so_libs;
4064
            push @paths, $base . $path;;
4065
        }
4066
    }
4067
 
4068
    #
4069
    #   Returns paths found
4070
    #
4071
    return @paths;
4072
}
4073
 
4074
#-------------------------------------------------------------------------------
247 dpurdie 4075
# Function        : BuildAddKnownFile
4076
#
4077
# Description     : Save the file as a file that will be known  to the JATS
4078
#                   makefiles. It will be available SRCS, but will not be a
4079
#                   part of any object list.
4080
#
4081
#                   Known Files will be deleted on clobber
4082
#
4083
# Inputs          : $path
4084
#                   $file
289 dpurdie 4085
#                   $noadd                    - Don't add to known
247 dpurdie 4086
#
4087
# Returns         : Path and filename
4088
#
4089
 
4090
sub BuildAddKnownFile
4091
{
289 dpurdie 4092
    my ($path, $file, $noadd) = @_;
247 dpurdie 4093
    $path .= '/'. $file;
2450 dpurdie 4094
    $path =~ tr~/~/~s;
289 dpurdie 4095
    $BUILD_KNOWNFILES {$file} = $path
4096
        unless ( defined($noadd) && $noadd);
4003 dpurdie 4097
 
3967 dpurdie 4098
    ToolsetFile( $path )
4099
        unless ($Clobber);
4100
 
247 dpurdie 4101
    return $path;
4102
}
4103
 
4104
#-------------------------------------------------------------------------------
5410 dpurdie 4105
# Function        : abtWarning 
4106
#
4107
# Description     : User Error, Build System Warning
4108
#                   Used to tighten up builds, but to retain BuildSystem compatability
4109
#
4110
#                   Must use "ErrorDoExit();" to force termination
4111
#                   Multiple error messages can be displayed before termination
4112
# 
4113
#                   ABT Mode is a bit more forgiving, but only for backward compatability
4114
#                   Otherwise force users to fix the build.pl files.
4115
#
4116
# Inputs          : $msg            - Message to display 
4117
#
4118
# Returns         : May not return
4119
#
4120
sub abtWarning
4121
{
4122
    my ($msg) = @_;
4123
    if ( $::GBE_ABT ) 
4124
    {
4125
        Warning( $msg . ' -- ignored in ABT Mode' );
4126
        return;
4127
    }
4128
    ReportError($msg);
4129
}
4130
 
4131
#-------------------------------------------------------------------------------
227 dpurdie 4132
# Function        : Usage
4133
#
4134
# Description     : Display program usage information
4135
#
4136
# Inputs          : args            - Text message to display
4137
#
4138
#                   $opt_help       - Level of verbose ness
4139
#
4140
# Returns         : Does not return
4141
#                   This function will exit
4142
#
4143
sub Usage
4144
{
4145
    my( $msg ) = @_;
4146
    my %usage_args;
4147
 
4148
    #
4149
    #   Create a hash of arguments for the pod2usage function
4150
    #
4151
    $usage_args{'-input'} = __FILE__;
4152
    $usage_args{'-exitval'} = 42;
4153
    $usage_args{'-message'} = "\nbuildlib $msg\n" if $msg;
4154
    $usage_args{'-verbose'} = $opt_help < 3 ? $opt_help - 1 : 3 if ( $opt_help );
4155
 
4156
    #
4157
    #   Generate nice help
4158
    #
4159
    pod2usage(\%usage_args);
4160
}
4161
 
4162
#-------------------------------------------------------------------------------
4163
#   Documentation
4164
#
4165
 
4166
=pod
4167
 
361 dpurdie 4168
=for htmltoc    JATS::build
4169
 
227 dpurdie 4170
=head1 NAME
4171
 
361 dpurdie 4172
build - Build Environment and Makefiles
227 dpurdie 4173
 
4174
=head1 SYNOPSIS
4175
 
4176
jats build [options] [command]
4177
 
4178
     [perl buildlib.pl [options] PWD [command]]
4179
 
4180
 Options:
331 dpurdie 4181
    -help          - Display terse usage
361 dpurdie 4182
    -help -help    - Display verbose usage
331 dpurdie 4183
    -man           - Display internal manual
4184
    -verbose[=n]   - Set level of progress verbosity
4185
    -debug[=n]     - Set the debug level
4186
    -nolog         - Do not generate/update Changelog
4187
    -cache         - Cache packages in the local dpkg_package cache
361 dpurdie 4188
    -cache -cache  - Forced refresh dependent packages in the local cache
331 dpurdie 4189
    -package       - Ignore packages that are not available and continue
2078 dpurdie 4190
    -nopackages    - Ignore package processing directives
331 dpurdie 4191
    -forcebuildpkg - Treat LinkPkgArchive directives as BuildPkgArchive
361 dpurdie 4192
                     Also suppress the use of symlinks so that the physical
4193
                     file will be copied locally.
331 dpurdie 4194
    -[no]force     - Force build even if build.pl is not newer
363 dpurdie 4195
                     Default: -force
4778 dpurdie 4196
    -[no]generic   - Build system sanity test
4197
                     Default: Do not test
227 dpurdie 4198
 
4199
 Sticky settings:
331 dpurdie 4200
    -all           - Build for all platforms ignoring GBE_BUILDFILTER
4201
    -expert[=n]    - Relaxing dependency checks on the user makefiles
227 dpurdie 4202
 
4203
 Commands:
361 dpurdie 4204
    changelog      - Only update ChangeLog.
2078 dpurdie 4205
    clobber        - Remove generated build system (eg Makefiles).
361 dpurdie 4206
    interface      - Only (re)build the interface tree, including ChangeLog.
4207
    rootonly       - Only (re)build the root directory.
227 dpurdie 4208
 
4209
=head1 OPTIONS
4210
 
4211
=over 8
4212
 
331 dpurdie 4213
=item B<-help>
227 dpurdie 4214
 
4215
Print a brief help message and exits.
4216
 
4217
=item B<-help -help>
4218
 
4219
Print a detailed help message with an explanation for each option.
4220
 
4221
=item B<-man>
4222
 
4223
Prints the manual page and exits.
4224
 
331 dpurdie 4225
=item B<-verbose[=n]>
227 dpurdie 4226
 
261 dpurdie 4227
Increases program output.
227 dpurdie 4228
 
261 dpurdie 4229
If an argument is provided, then it will be used to set the level, otherwise the
4230
existing level will be incremented. This option may be specified multiple times.
227 dpurdie 4231
 
261 dpurdie 4232
=item B<-debug>
4233
 
227 dpurdie 4234
Increases program output. Enable internal debugging messages to generate detailed
4235
progress information.
4236
 
261 dpurdie 4237
If an argument is provided, then it will be used to set the level, otherwise the
4238
existing level will be incremented. This option may be specified multiple times.
4239
 
331 dpurdie 4240
=item B<-nolog>
227 dpurdie 4241
 
4242
Do not generate or update the ChangeLog maintained when a CVS directory is detected
4243
in the build directory.
4244
 
331 dpurdie 4245
=item B<-cache>
227 dpurdie 4246
 
4247
This option will cause dependent packages to be cached in the local
4248
dpkg_archive cache.
4249
 
4250
If the option is used twice then the packages will be forcibly refreshed.
4251
 
331 dpurdie 4252
=item B<-package>
227 dpurdie 4253
 
4254
This option will cause the build process to ignore packages that cannot be
4255
located. The package build may fail at a later stage.
4256
 
4257
This option is used by the Auto Build Tool to handle packages that may not be
4258
needed in all builds.
4259
 
2078 dpurdie 4260
=item B<-nopackage>
4261
 
4262
This options will cause all the directives that process external packages to be
4263
ignored.
4264
 
4265
This directive has limited use. It can be used in conjunction with the
4266
'interface' build command in order to create Version Information files in a
4267
sandbox where the required packages do not yet exist.
4268
 
331 dpurdie 4269
=item B<-forcebuildpkg>
227 dpurdie 4270
 
4271
This option will force LinkPkgArchive directives to be treated as
4272
BuildPkgArchive directives. The result is that the 'interface' directory will be
4273
populated with the contents of all dependent packages. Moreover, on a Unix
4274
machine, the files will be copied and not referenced with a soft link.
4275
 
4276
This may be useful for:
4277
 
4278
=over 8
4279
 
361 dpurdie 4280
=item *
227 dpurdie 4281
 
361 dpurdie 4282
Remote Development
227 dpurdie 4283
 
361 dpurdie 4284
=item *
227 dpurdie 4285
 
361 dpurdie 4286
Collecting header files for scanning
4287
 
4288
=item *
4289
 
4290
Local modification of files for test/debug/development
4291
 
227 dpurdie 4292
=back
4293
 
331 dpurdie 4294
=item B<-[no]force>
227 dpurdie 4295
 
331 dpurdie 4296
The '-noforce' option will only perform a build, if the build.pl file
363 dpurdie 4297
has been modified, or the buildfilter has changed, since the last build.
331 dpurdie 4298
 
363 dpurdie 4299
The default operation will always force a build.
331 dpurdie 4300
 
4778 dpurdie 4301
=item B<-[no]generic>
4302
 
4303
If used, this option will perform a sanity test on the build type. If set to 
4304
Generic then the build must be a GENERIC build. If set to noGeneric then the build
4305
must not be a GENERIC build.
4306
 
4307
The default is to not perform the test.
4308
 
4309
This option is intended to be used by the automated build system.
4310
 
331 dpurdie 4311
=item B<-all>
4312
 
227 dpurdie 4313
This option will cause the build process to generate makefiles for all
4314
possible build targets ignoring the use of GBE_BUILDFILTER.
4315
 
4316
This option is sticky. Once used in a build it will be retained when makefiles
4317
are rebuilt.
4318
 
331 dpurdie 4319
=item B<-expert[=n]>
227 dpurdie 4320
 
4321
This option causes the generation of makefiles with relaxed dependancy checks.
4322
 
261 dpurdie 4323
If an argument is provided, then it will be used to set the level, otherwise a
4324
level of '1' will be set.
4325
 
227 dpurdie 4326
The makefiles will have no dependancy between the makefiles and the JATS build
4327
files or the users makefile. If the user's makefile.pl is changed then JATS
4328
will not detect the change and will not rebuild the makefiles. The user manually
4329
force the rebuild with the command 'jats rebuild'.
4330
 
4331
This option should be used with care and with full knowledge of its impact.
4332
 
4333
This option is sticky. Once used in a build it will be retained when makefiles
363 dpurdie 4334
are rebuilt. It will only be lost when the next 'jats build' is performed.
227 dpurdie 4335
 
261 dpurdie 4336
The effect of the option can be changed when the makefiles are processed. This
4337
option simply sets the default' mode of operation.
4338
 
227 dpurdie 4339
=item B<changelog>
4340
 
4341
This command will only update the CVS change log.
4342
 
4343
=item B<interface>
4344
 
4345
This command will only build, or rebuild, the 'interface' directory and the
4346
changelog ( if required ).
4347
 
261 dpurdie 4348
This command will not build, or rebuild, the root directory. The build
227 dpurdie 4349
process will not recurse through the subdirectories creating makefiles.
4350
 
261 dpurdie 4351
=item B<rootonly>
4352
 
4353
This command will only build, or rebuild, the 'interface' directory, the
4354
changelog (if required) and the root-level makefiles.
4355
 
4356
The build process will not recurse through the subdirectories creating
4357
makefiles. These can be made on-demand by jats if a 'make' command is issued.
4358
 
227 dpurdie 4359
=item B<clobber>
4360
 
4361
This command will remove generated build system files and directories.
4362
 
4363
=back
4364
 
4365
=head1 DESCRIPTION
4366
 
4367
The default build process will parse the user's build.pl file and create the
4368
'interface' directory before creating makefiles for each target platform.
4369
 
4370
The 'build' process simply generates the build sandbox. It does not invoke the
4371
generated makefiles. This must be done by the user in a different phase.
4372
 
4373
The 'build' process need only be invoked if the build.pl file has changed. The
4374
generated makefiles will detected changes to the makefile.pl's and cause them to
4375
be generated as required. The 'build' step sets up the sandboxes external
4376
environment.
4377
 
4378
=head1 INVOCATION
4379
 
4380
This perl library (buildlib.pl) is not designed to be invoked directly by the
4381
user. It should be invoked through a 'build.pl' file. Moreover, for historical
4382
reasons, the build.pl is not easily invoked. It is best to only invoke the
4383
'build' process via the JATS wrapper scripts : jats.bat or jats.sh.
4384
 
331 dpurdie 4385
The build.pl file must be invoked with one fixed arguments, followed by user
227 dpurdie 4386
options and subcommands
4387
 
4388
=over 8
4389
 
361 dpurdie 4390
=item   1
227 dpurdie 4391
 
361 dpurdie 4392
The current working directory
4393
 
227 dpurdie 4394
This could have been derived directly by the program, rather than having it
4395
passed in.
4396
 
361 dpurdie 4397
=item   2
227 dpurdie 4398
 
361 dpurdie 4399
Options and commands may follow the first two mandatory arguments.
4400
 
227 dpurdie 4401
=back
4402
 
4403
The build.pl file must 'require' the buildlib.pl and makelib.pl. The preferred
4404
code is:
4405
 
4406
=over 8
4407
 
4408
    build.pl: First statements
4409
    $MAKELIB_PL     = "$ENV{ GBE_TOOLS }/makelib.pl";
4410
    $BUILDLIB_PL    = "$ENV{ GBE_TOOLS }/buildlib.pl";
4411
 
4412
    require         "$BUILDLIB_PL";
4413
    require         "$MAKELIB_PL";
4414
 
4415
=back
4416
 
4417
=cut
4418
 
4419
1;