Subversion Repositories DevTools

Rev

Rev 1107 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1105 dpurdie 1
########################################################################
2
# Copyright (C) 2008 ERG Limited, All rights reserved
3
#
4
# Module name   : Proc_day0fs_script.pl
5
# Module type   : Makefile system
6
# Compiler(s)   : Perl
7
# Environment(s): jats
8
#
9
# Description   :
10
#
11
# Usage:
12
#
13
#......................................................................#
14
 
15
require 5.008_002;
16
 
17
use strict;
18
use warnings;
19
 
20
use Pod::Usage;
21
use Getopt::Long;
22
use File::Path;
23
use File::Copy;
24
 
25
use FindBin;                                    # Determine the current directory
26
use lib "$FindBin::Bin";                        # Allow Modules in current directory
27
 
28
use JatsError;
29
use JatsSystem;
30
use FileUtils;
31
use JatsCopy qw(SetCopyDirDefaults DeleteDir CopyDir CreateDir);
32
use CreateSdImage qw( CreateSdImage );
33
 
34
#
35
#
36
#   Global Variables
37
#
38
my $VERSION = 1.0;
39
our $AUTOLOAD;
40
my $BUILD = 'build';                        # Build subdir
41
my $WORK = "${BUILD}/image";
42
 
43
my $source_specified = 0;                   # Ensure that source is specified
44
my $output_image = 0;                       # Ensure output is specified
45
my $output_sd = 0;
46
 
47
#
48
#   Command line options
49
#
50
my $opt_debug   = $ENV{'GBE_DEBUG'};        # Allow global debug
51
my $opt_verbose = $ENV{'GBE_VERBOSE'};      # Allow global verbose
52
my $opt_vargs;                              # Verbose arg
53
my $opt_help = 0;
54
my $opt_manual = 0;
55
my $opt_clean = 0;
56
my $opt_platform;
57
my $opt_type;
58
my $opt_buildname;
59
my $opt_packagedir;
60
my $opt_interfacedir;
61
my $opt_compilerpath;
62
my $opt_product;
63
my $opt_packagebindir;
64
our $opt_buildroot;
65
my $opt_target;
66
my $opt_version;
67
my $opt_userscript;
68
 
69
#-------------------------------------------------------------------------------
70
# Function        : Mainline Entry Point
71
#
72
# Description     :
73
#
74
# Inputs          :
75
#
76
my $result = GetOptions (
77
                "help+"             => \$opt_help,
78
                "manual"            => \$opt_manual,
79
                "verbose:s"         => \$opt_vargs,
80
                "clean"             => \$opt_clean,
81
                "Platform=s"        => \$opt_platform,
82
                "Type=s"            => \$opt_type,
83
                "BuildName=s"       => \$opt_buildname,
84
                "PackageDir=s"      => \$opt_packagedir,
85
                "InterfaceDir=s"    => \$opt_interfacedir,
86
                "CompilerPath=s"    => \$opt_compilerpath,
87
                "Product=s"         => \$opt_product,
88
                "PackageBinDir=s"   => \$opt_packagebindir,
89
                "BuildRoot=s"       => \$opt_buildroot,
90
                "Target=s"          => \$opt_target,
91
                "BuildVersion=s"    => \$opt_version,
92
                "UserScript=s"      => \$opt_userscript,
93
 
94
    );
95
 
96
#
97
#   Process help and manual options
98
#
99
pod2usage(-verbose => 0, -message => "Version: $VERSION")  if ($opt_help == 1  || ! $result);
100
pod2usage(-verbose => 1)  if ($opt_help == 2 );
101
pod2usage(-verbose => 2)  if ($opt_manual || ($opt_help > 2));
102
 
103
#
104
#   Configure the error reporting process now that we have the user options
105
#
106
$opt_verbose++ unless ( $opt_vargs eq '@' );
107
ErrorConfig( 'name'    => 'Proc_Day0fs',
108
             'verbose' => $opt_verbose );
109
 
110
#
111
#   Configure the System command to fail on any error
112
#
113
SystemConfig ( ExitOnError => 1 );
114
SetCopyDirDefaults ( 'EmptyDirs' => 1 ,Log => 0 );
115
 
116
#
117
#   Init the FileSystem Uiltity interface
118
#
119
InitFileUtils();
120
 
121
#
122
#   Ensure that we have all required options
123
#
124
Error ("CompilePath not set")       unless ( $opt_compilerpath );
125
Error ("Platform not set")          unless ( $opt_platform );
126
Error ("Type not set")              unless ( $opt_type );
127
Error ("BuildName not set")         unless ( $opt_buildname );
128
Error ("PackageBinDir not set")     unless ( $opt_packagebindir );
129
Error ("InterfaceDir not set")      unless ( $opt_interfacedir );
130
Error ("CompilePath not set")       unless ( $opt_compilerpath );
131
Error ("Product not set")           unless ( $opt_product );
132
Error ("BuildRoot not set")         unless ( $opt_buildroot );
133
Error ("Target not set")            unless ( $opt_target );
134
Error ("User Script not set")       unless ( $opt_userscript );
135
 
136
#
137
#   Calculate a few paths
138
#
139
my $TOOLSUITE = $opt_compilerpath;
140
$TOOLSUITE =~ s~^.*/~~;
141
$TOOLSUITE =~ s~-gcc$~~;
142
 
143
my $CROSSLIBS = $opt_compilerpath;
144
$CROSSLIBS =~ s~/bin/.*$~~;
145
$CROSSLIBS .= "/${TOOLSUITE}/lib";
146
 
147
my $CROSSEXE = $opt_compilerpath;
148
$CROSSEXE =~ s~/bin/.*$~~;
149
$CROSSEXE .= "/${TOOLSUITE}";
150
 
151
 
152
my $CROSS_COMPILE = $opt_compilerpath;
153
$CROSS_COMPILE =~ s~gcc$~~;
154
 
155
my $CROSS_STRIP = ${CROSS_COMPILE} . "strip";
156
 
157
#
158
#   Display variables used
159
#
160
Message    "======================================================================";
161
Message    "Build day0 file system";
162
Message    "           Package: ${opt_buildname}";
163
Message    "           Version: ${opt_version}";
164
Message    "      Building for: ${opt_platform}, $opt_target";
165
Message    "           Product: ${opt_product}";
166
Message    "              Type: ${opt_type}";
167
Message    "            Script: ${opt_userscript}";
168
Verbose    "           Verbose: ${opt_verbose}";
169
Message    "         BuildRoot: ${opt_buildroot}";
170
Verbose    "         BuildRoot: ${opt_buildroot}";
171
Verbose    "      InterfaceDir: ${opt_interfacedir}";
172
Verbose    "     CROSS_COMPILE: ${CROSS_COMPILE}";
173
Verbose    "         CROSSLIBS: ${CROSSLIBS}";
174
Verbose    "       CROSS_STRIP: ${CROSS_STRIP}";
175
Message    "======================================================================";
176
 
177
#
178
#   Perform Clean up
179
#   Invoked during "make clean" or "make clobber"
180
#
181
if ( $opt_clean )
182
{
183
    Message ("Remove build directory: $BUILD");
184
    rmtree( $BUILD );
185
    exit;
186
}
187
 
188
#
189
#   Have setup the basics
190
#   Invoke the user script to drive the remainder of the process
191
#       The script should only contain known directives
192
#       The directives will build up data structures that will be processed
193
#       after the script has been read
194
#
195
#
196
Message ("Process User Script: $opt_userscript");
197
Error ("Board Specfic file Not found: $opt_userscript") unless ( -f $opt_userscript );
198
require $opt_userscript;
199
 
200
#
201
#   The process of requiring the user script
202
#   will have done all the required work
203
#   Perform minor sanity testing
204
#
205
#
206
#   All done
207
#
208
Error ( "No package output specified" )
209
    unless ( $output_image || $output_sd );
210
exit 0;
211
 
212
 
213
################################################################################
214
################################################################################
215
#
216
#   The following functions are intended to be used to manipulate files within
217
#   the output image.
218
#
219
#   These may be used by the board specfic functions.
220
#
221
################################################################################
222
 
223
#-------------------------------------------------------------------------------
224
# Function        : Day0Source
225
#
226
# Description     : Determine the source of the Day0 File System
227
#                   Use of this directive is mandatory
228
#
229
#
230
# Inputs          : Options
231
#                       --Dir=name              - Source dir
232
#                       --Image=name            - Source image
233
#
234
# Returns         : Nothing
235
#
236
sub Day0Source
237
{
238
    my ($opt) = @_;
239
    #
240
    #   Can only use this directive ONCE
241
    #
242
    Error ("Multiple Day0Source directives not allowed")
243
        if ( $source_specified++ );
244
 
245
    #
246
    #   Start with a clean slate
247
    #
248
    DeleteDir ( $WORK );
249
 
250
    #
251
    #   Process options
252
    #
253
    if ( $opt =~ /^--Dir=(.+)/ ) {
254
        #
255
        #   User has specified a directory
256
        #   Copy the entire directory to the work area
257
        #
258
        Message ("Copy in Day0 source directory: $WORK");
259
        CopyDir ( $1, $WORK, 'DeleteFirst' => 1 );
260
 
261
    } elsif ( $opt =~ /^--Image=(.+)/ ) {
262
 
263
        #
264
        #   User has specified an Image
265
        #   Locate the image and extract it into the work area
266
        #
267
        my $name = $1;
268
        Message ("Extract File System Image: $name");
269
 
270
        #
271
        #   File will come from a Package
272
        #   This is where the tool places output files
273
        #
274
        my $fname = Internal::LocateFile ('bin', $name . '.tgz' );
275
        Error ("Cannot locate Day0 source image: $name")
276
            unless $fname;
277
 
278
        #
279
        #   Create a Tar command
280
        #   Assumes the presence of a GNU style tar
281
        #
282
        CreateDir ( $WORK );
283
        System ( 'gtar',
284
                 '--extract',
285
                 '--file',  $fname,
286
                 '--gzip',
287
                 IsVerbose(1) ? ( '--verbose' ) : (),
288
                 '--directory', $WORK,
289
                 );
290
 
291
    } else {
292
        Error ("Unknown Day0Source option: $opt");
293
    }
294
}
295
 
296
 
297
#-------------------------------------------------------------------------------
298
# Function        : Day0Operation
299
#
300
# Description     : Perform one of the special Day0 Operations
301
#
302
# Inputs          : $subfunction            - Sub function to perform
303
#                   @opts                   - Sub function options
304
#
305
# Returns         : Nothing
306
#
307
sub Day0Operation
308
{
309
    Error ("Day0Source must be specified first")
310
        unless ( $source_specified );
311
 
312
    #
313
    #   Perform the Day0Operation
314
    #   These are specialised operations and normally only performed on the
315
    #   the basic skelton.
316
    #
317
    #   Dispatch to the required function
318
    #
319
    my $opt = shift (@_);
320
    if ( my $fref = UNIVERSAL::can ( 'Day0Ops', lc($opt) ) )
321
    {
322
        &$fref( @_ );
323
    }
324
    else
325
    {
326
        Error ("Unknown Day0Operation option: $opt @_");
327
    }
328
}
329
 
330
#-------------------------------------------------------------------------------
331
# Function        : Day0BuildImage
332
#
333
# Description     : Package up the created image as a tar-zip file
334
#                   This allows the Image to be processed again later
335
#
336
# Inputs          : Options
337
#                       --name=Name             - Output Name
338
#
339
# Returns         : 
340
#
341
sub Day0BuildImage
342
{
343
    my $name = 'Day0Image';
344
    Message ("Create File System Image; $name");
345
 
346
    #
347
    #   Indicate that we have created some output
348
    #
349
    Error ("Day0Source must be specified first")
350
        unless ( $source_specified );
351
    $output_image++;
352
 
353
    #
354
    #   Process user options
355
    #
356
    foreach  ( @_ )
357
    {
358
        if ( m~^--Name=(.+)~i ) {
359
            $name = $1;
360
        } else {
361
            Error ("Day0BuildImage: Unknown option: $_");
362
        }
363
    }
364
 
365
    #
366
    #   Place the file in the BIN directory
367
    #   Have no reall good reason
368
    #
369
    $name = $opt_packagebindir . '/' . $name . '.tgz';
370
    CreateDir ( $opt_packagebindir);
371
 
372
    #
373
    #   Create a Tar command
374
    #   Assumes the presence of a GNU style tar
375
    #
376
    System ( 'gtar',
377
             '--create',
378
             '--file',  $name,
379
             '--gzip',
380
             IsVerbose(1) ? ( '--verbose' ) : (),
381
             '--directory', $WORK,
382
             '.' );
383
}
384
 
385
#-------------------------------------------------------------------------------
386
# Function        : Day0BuildSdImage
387
#
388
# Description     : Package up the created image and create an SD memory image
389
#                   This is destructive and can only be done one
390
#
391
# Inputs          : Options
392
#                       --disk_blocks           - Size the output disk
393
#
394
# Returns         : 
395
#
396
sub Day0BuildSdImage
397
{
398
    my $size = 501248;
399
    my $debug;
400
 
401
    #
402
    #   Ensure that some work is being done
403
    #
404
    Error ("Day0Source must be specified first")
405
        unless ( $source_specified );
406
 
407
    Error ("Cannot create multiple SD images")
408
        if ( $output_sd++ );
409
 
410
    #
411
    #   Process user options
412
    #
413
    foreach  ( @_ )
414
    {
415
        if ( m~^--disk-blocks=(\d+)$~i ) {
416
            $size = $1;
417
        } elsif ( m~^--debug~i ) {
418
            $debug = 1;
419
        } else {
420
            Error ("Day0BuildSdImage: Unknown option: $_");
421
        }
422
    }
423
 
424
    #
425
    #   Perform specific processing on the image
426
    #
427
 
428
    #
429
    #   Scan the skeleton and process .LINKS files
430
    #   File links do not store well in version control systems
431
    #   NOTE: .LINKS are a local invention and not a part of e2fsimage like
432
    #         .DEVICES on which they are modelled.
433
    #
434
    Message ("Locate LINKFILES in $WORK");
435
    foreach my $linkfile ( Internal::FindFiles( $WORK, ".LINKS" ))
436
    {
437
        my $BASEDIR = StripFileExt( $linkfile );
438
        $BASEDIR =~ s~^$WORK/~~;
439
        Message "Expand links: $BASEDIR";
440
        open (LF, "<", $linkfile ) || Error ("Cannot open link file: $linkfile" );
441
        while ( <LF> )
442
        {
443
            chomp;
444
            next if ( m~^#~ );
445
            next unless ( $_ );
446
            my ($link, $file) = split;
447
 
448
            Internal::MakeSymLink($file ,"$BASEDIR/$link", '--NoDotDot' );
449
        }
450
        close (LF);
451
        unlink $linkfile;
452
    }
453
 
454
 
455
    #   Update the Shared Library Cache
456
    #
457
    Message ("Create Shared Library Cache");
458
    System ('/sbin/ldconfig', '-r', $WORK );
459
 
460
    #
461
    #   Make every thing executable
462
    #       This is good for directories
463
    #       This is good for all files. Shouldn't be an issue to files in /etc
464
    #
465
    Message ("Mark files as executable");
466
    foreach my $dir ( glob ("$WORK/*") )
467
    {
468
        next if ( $dir =~ m~/etc$~ );
469
        System ('chmod', '-R', 'a+rx', $dir );
470
    }
471
 
472
    foreach my $dir ( glob ("$WORK/etc/*") )
473
    {
474
        next unless ( -d $dir );
475
        System ('chmod', '-R', 'a+rx', $dir );
476
    }
477
 
478
    #
479
    #   Special considertaion
480
    #       /etc/busybox.conf   - Accessible by root
481
    #       /bin/busybox        - setuid
482
    #
483
    System ('chmod', '600',  "$WORK/etc/busybox.conf" );
484
    System ('chmod', '4755', "$WORK/bin/busybox" );
485
 
486
    #
487
    #   Stop here if debugging
488
    #   Don't create the actual image as the process destroys the image
489
    #
490
    Error ("Day0BuildSdImage: Debug Image. SD Image not built")
491
        if ( $debug );
492
 
493
    #
494
    #   Invoke SD build function
495
    #   Held in another package to make this one readable
496
    #
497
    my $name = "${opt_buildname}-${opt_version}-${opt_target}";
498
    CreateSdImage( $opt_packagebindir, $name, $WORK, $BUILD, $size );
499
}
500
 
501
#-------------------------------------------------------------------------------
502
# Function        : AddInitScript
503
#
504
# Description     : Add an Init Script to the target
505
#                   Optionally create start and stop links
506
#
507
#                   Existing links will always be delete
508
#
509
# Inputs          : $script     - Name of the init script
510
#                   $start      - Start Number
511
#                   $stop       - Stop Number
512
#                   Options:
513
#                       --NoCopy    - Don't copy the script, just add links
514
#
515
# Returns         : 
516
#
517
sub AddInitScript
518
{
519
    my ( $script, $start, $stop, @opts ) = @_;
520
 
521
    Error ("Day0Source must be specified first")
522
        unless ( $source_specified );
523
 
524
    Message ("AddInitScript: $script, $start, $stop");
525
 
526
    my $tdir = "/etc/init.d/init.d";
527
    my $base = StripDir($script);
528
 
529
    unless ( grep '^--NoCopy', @opts )
530
    {
531
        ::CopyFile( $script, $tdir );
532
    }
533
 
534
    #
535
    #   Delete any existing links
536
    #
537
    foreach my $file ( glob("$WORK/etc/init.d/*$base") )
538
    {
539
        next unless ( $file =~ m~/[KS][\d]+${base}~ );
540
        unlink $file;
541
    }
542
 
543
    my $link;
544
    if ( $start )
545
    {
546
        $link = sprintf ("/etc/init.d/S%2.2d%s", $start, $base );
547
        Internal::MakeSymLink( "$tdir/$base", $link);
548
    }
549
 
550
    if ( $stop )
551
    {
552
        $link = sprintf ("/etc/init.d/K%2.2d%s", $stop, $base );
553
        Internal::MakeSymLink( "$tdir/$base", $link);
554
    }
555
}
556
 
557
#-------------------------------------------------------------------------------
558
# Function        : EchoFile
559
#
560
# Description     : Echo simple text to a file
561
#
562
# Inputs          : $file   - Within the output workspace
563
#                   $text
564
#
565
# Returns         : 
566
#
567
sub EchoFile
568
{
569
    my ($file, $text) = @_;
570
    Error ("Day0Source must be specified first")
571
        unless ( $source_specified );
572
 
573
    $file = $WORK . '/' . $file;
574
    $file =~ s~//~/~;
575
 
576
    unlink $file;
577
    open (DT, ">", $file ) || Error ("Cannot create $file");
578
    print DT  $text || Error ("Cannot print to $file");
579
    close DT;
580
}
581
 
582
#-------------------------------------------------------------------------------
583
# Function        : CopyPkgDir
584
#
585
# Description     : Copy a directory to a target dir
586
#                   Source directory is within a 'package'
587
#                   Does not delete the target directory, but will add files
588
#
589
#                   Currently does not support
590
#                       Recursion
591
#                       Flattening
592
#
593
#
594
# Inputs          : $src_dir    - Within a package
595
#                   $dst_dir    - Within the output workspace
596
#
597
#                   Options:
598
#                       --FilterIn=Filter           Simple filter
599
#                       --FilterOut=Filter          Simple filter
600
#
601
# Returns         :
602
#
603
sub CopyPkgDir
604
{
605
    my @filter_out;
606
    my @filter_in;
607
    my @args;
608
 
609
    Error ("Day0Source must be specified first")
610
        unless ( $source_specified );
611
 
612
    #
613
    #   Process options
614
    #
615
    foreach  ( @_ )
616
    {
617
        if ( m/^--FilterIn=(.+)/ ) {
618
            push @filter_in, $1;
619
 
620
        } elsif ( m/^--FilterOut=(.+)/ ) {
621
            push @filter_out, $1;
622
 
623
        } elsif ( m/^-/ ) {
624
            Error("CopyPkgDir: Unknown option: $_");
625
 
626
        } else {
627
            push @args, $_;
628
        }
629
    }
630
    my ($src_dir, $dst_dir) = @args;
631
    #
632
    #   Calculate the destination path
633
    #
634
    $dst_dir = $WORK . '/' . $dst_dir;
635
    $dst_dir =~ s~//~/~;
636
 
637
    #
638
    #   Validate source dir
639
    #
640
    my $full_src_dir = "$opt_interfacedir/$src_dir";
641
    Error("CopyPkgDir: Source dir not found: $src_dir") unless ( -d $full_src_dir );
642
 
643
    #
644
    #   Copy as required
645
    #
646
    CopyDir ( $full_src_dir, $dst_dir,
647
                    'Flatten' => 1,
648
                    'NoSubDirs' => 1,
649
                    'Ignore' =>  \@filter_out,
650
                    'Match' => \@filter_in,
651
                    );
652
}
653
 
654
#-------------------------------------------------------------------------------
655
# Function        : CopyPackage
656
#
657
# Description     : Copy in files from a package located in the interface
658
#                   directory.
659
#
660
#                   The source directory may be:
661
#                       pkg/<platform>
662
#                       pkg/<product>
663
#                       pkg/<target>
664
#
665
# Inputs          : $section    - Section to search
666
#                   $file       - Source Path within a package
667
#                   @llist      - list of softlinks
668
#                                 Abs or Relative to destination dir
669
#
670
#                   Embedded Options:
671
#                               --Dest=Dir (Default is taken from $file)
672
#                               --LinkFile (Append to .LINKS file)
673
#                               --Rename=Name
674
#
675
# Returns         :  Path to the target file
676
#
677
sub CopyPackage
678
{
679
    my $dest;
680
    my $isa_linkfile;
681
    my @args;
682
    my $dfile;
683
    my @options;
684
 
685
    Error ("Day0Source must be specified first")
686
        unless ( $source_specified );
687
 
688
    #
689
    #   Process and Remove options
690
    #
691
    foreach  ( @_ )
692
    {
693
        if ( m/^--Dest=(.*)/ ) {
694
            $dest = $1 . '/xxx';
695
 
696
        } elsif ( m/^--LinkFile/ ) {
697
            $isa_linkfile = 1;
698
 
699
        } elsif ( m/^--Rename=(.+)/ ) {
700
            push @options, $_;
701
 
702
        } elsif ( m/^--/ ) {
703
            Error ("CopyPackage: Unknown option: $_");
704
 
705
        } else {
706
            push @args, $_;
707
 
708
        }
709
    }
710
 
711
    my ($section, $file, @llist) = @args;
712
 
713
    #
714
    #   Default destination is the same as the source
715
    #
716
    $dest = $file unless ( $dest );
717
    my $dest_dir = StripFileExt($dest);
718
 
719
    my $tfile = Internal::LocateFile($section, $file);
720
    Error ("CopyPackage: File not found: $file") unless $tfile;
721
 
722
    #
723
    #   LinkFiles are special
724
    #   They get concatenated to any existing Link File
725
    #
726
    if ( $isa_linkfile )
727
    {
728
        CatFile ( $tfile, "$dest_dir/.LINKS" );
729
    }
730
    else
731
    {
732
        $dfile = CopyFile ($tfile, $dest_dir, @options );
733
        foreach my $lname ( @llist )
734
        {
735
            $lname = $dest_dir . '/' . $lname unless ( $lname =~ m ~^/~ );
736
            my $dest_file = $dest_dir . '/' . StripDir($dfile);
737
            Internal::MakeSymLink($dest_file ,$lname);
738
        }
739
    }
740
 
741
    return $dfile;
742
}
743
 
744
#-------------------------------------------------------------------------------
745
# Function        : CatFile
746
#
747
# Description     : Copy a file to the end of a file
748
#
749
# Inputs          : $src
750
#                   $dst    - Within the output workspace
751
#
752
# Returns         :
753
#
754
sub CatFile
755
{
756
    my ($src, $dst) = @_;
757
    $dst = $WORK . '/' . $dst;
758
    $dst =~ s~//~/~;
759
    Verbose ("CatFile: $src, $dst");
760
 
761
    Error ("Day0Source must be specified first")
762
        unless ( $source_specified );
763
 
764
    open (SF, '<', $src)  || Error ("CatFile: Cannot open $src");
765
    open (DF, '>>', $dst) || Error ("CatFile: Cannot create:$dst");
766
    while ( <SF> )
767
    {
768
        print DF $_;
769
    }
770
    close (SF);
771
    close (DF);
772
}
773
 
774
 
775
#-------------------------------------------------------------------------------
776
# Function        : CopyFile
777
#
778
# Description     : Copy a file to a target dir
779
#
780
# Inputs          : $src
781
#                   $dst_dir    - Within the output workspace
782
#                   Options     - Optional flags
783
#                                 --Symlink
784
#                                   Copies symlink, not symlink target
785
#                                 --Rename=xxx
786
#                                   Renames file
787
#
788
# Returns         : Full path to destination file
789
#
790
sub CopyFile
791
{
792
    my ($src, $dst_dir, @opts ) = @_;
793
    my $tfile = StripDir($src);
794
    my %opts;
795
 
796
    Error ("Day0Source must be specified first")
797
        unless ( $source_specified );
798
 
799
    #
800
    #   Extract options
801
    #
802
    foreach  ( @opts )
803
    {
804
        if ( m/^--Symlink/ ) {
805
            $opts{DuplicateLinks} = 1;
806
 
807
        } elsif ( m/^--Rename=(.+)/ ) {
808
            $tfile = $1;
809
 
810
        } else {
811
            Error("CopyFile: Unknown option: $_");
812
        }
813
    }
814
 
815
    #
816
    #   Calculate the destination path
817
    #
818
    $dst_dir = $WORK . '/' . $dst_dir;
819
    $dst_dir =~ s~//~/~;
820
 
821
    #
822
    #   Determine the full name of the target
823
    #
824
    my $dst_file = "$dst_dir/$tfile";
825
 
826
    Verbose ("CopyFile: $src, $dst_dir");
827
    return JatsCopy::CopyFile( $src, $dst_file, \%opts );
828
}
829
 
830
#-------------------------------------------------------------------------------
831
# Function        : AUTOLOAD
832
#
833
# Description     : Intercept bad user directives and issue a nice error message
834
#                   This is a simple routine to report unknown user directives
835
#                   It does not attempt to distinguish between user errors and
836
#                   programming errors. It assumes that the program has been
837
#                   tested. The function simply report filename and line number
838
#                   of the bad directive.
839
#
840
# Inputs          : Original function arguments ( not used )
841
#
842
# Returns         : This function does not return
843
#
844
sub AUTOLOAD
845
{
846
    my $fname = $::AUTOLOAD;
847
    $fname =~ s~^\w+::~~;
848
    my ($package, $filename, $line) = caller;
849
 
850
    Error ("Directive not known or not allowed in this context: $fname",
851
           "Directive: $fname( @_ );",
852
           "File: $filename, Line: $line" );
853
}
854
 
855
 
856
#-------------------------------------------------------------------------------
857
# Function        : FirstBoot
858
#
859
# Description     : Add a file to the first boot section
860
#                   Assumes that the firstboot directory is /var/afc/firstboot
861
#                   This is the default
862
#
863
# Inputs          : All options
864
#                       --Debian=xxx[,opts] - Locate debian package
865
#                                             Sub opts are:
866
#                                               --Arch=xxx
867
#                                               --Product=xxx
868
#                                               --Debug
869
#                                               --Prod
870
#                       --File=yyy          - Locate a files
871
#                       --Level=nn          - Level to run (default=50)
872
#
873
# Returns         : 
874
#
875
sub FirstBoot
876
{
877
    my  $file;
878
    my  $level = 50;
879
 
880
    Error ("Day0Source must be specified first")
881
        unless ( $source_specified );
882
 
883
    #
884
    #   Collect user items
885
    #
886
    foreach ( @_ )
887
    {
888
        if ( m~^--Debian=(.+)~ ) {
889
            Error ("FirstBoot: Multiple source files not supported in one directive: $_") if $file;
890
            $file = Internal::LocateDebianFile($1, $opt_target, $opt_product);
891
 
892
        } elsif ( m~^--File=(.+)~ ) {
893
            Error ("FirstBoot: Multiple source files not supported in one directive: $_") if $file;
894
            $file = $1;
895
 
896
        } elsif ( m~^--Level=(\d+)~ ) {
897
            $level = $1;
898
            Error ("FirstBoot: Invalid Level: $_") if ($level < 0 || $level > 99);
899
 
900
        } else {
901
            Error ("FirstBoot: Unknown option or argument: $_");
902
        }
903
    }
904
 
905
    #
906
    #   Insert the required file
907
    #       Prepend name with a two digit level
908
    #
909
    my $fname = sprintf ('%2.2d.%s', $level, StripDir($file)  );
910
    Message ("FirstBoot: $fname");
911
 
912
    CopyFile ( $file, '/var/afc/firstboot', "--Rename=$fname" );
913
}
914
 
915
################################################################################
916
################################################################################
917
#   
918
#   Package to contain DayOp opereration
919
#
920
package Day0Ops;
921
 
922
use strict;
923
use warnings;
924
 
925
 
926
use JatsError;
927
use JatsSystem;
928
use JatsCopy qw(SetCopyDirDefaults DeleteDir CopyDir CreateDir);
929
 
930
#-------------------------------------------------------------------------------
931
# Function        : hostname
932
#
933
# Description     : Insert hostname information into the target
934
#                       Insert /etc/devicetype
935
#                       Insert into hostname too
936
#
937
#
938
# Inputs          : 
939
#
940
# Returns         : 
941
#
942
sub hostname
943
{
944
    Message ("Insert Hostname an Devicename: ${opt_product}");
945
    ::EchoFile ( "/etc/devicetype", $opt_product );
946
    ::EchoFile ( "/etc/hostname", $opt_product );
947
    ::EchoFile ( "/etc/day0-version", "$opt_buildname $opt_version $opt_product $opt_platform $opt_target" );
948
}
949
 
950
#-------------------------------------------------------------------------------
951
# Function        : setupbusybox
952
#
953
# Description     : Insert busybox into the skeleton
954
#                   Locate busybox and associated links file
955
#
956
# Inputs          : None
957
#
958
# Returns         : Nothing
959
#
960
sub setupbusybox
961
{
962
    #
963
    #   Insert busybox into the skeleton
964
    #   Locate busybox and associated links file
965
    #
966
    Message ("Copy in busybox");
967
    my $bbfile  = ::CopyPackage ('bin', 'busybox',       "--Dest=bin" );
968
    my $bblinks = ::CopyPackage ('bin', 'busybox.links', "--Dest=bin" );
969
 
970
    #
971
    #   Expand the busybox links
972
    #   Use soft links. Expect that they will be easier to update in the field
973
    #   Keep the .links file on the target.
974
    #
975
    Message "Expand busybox links";
976
    open ( BBLINK, "<", $bblinks ) || Error ("Cannot open BusyBox Links file");
977
    while ( <BBLINK> )
978
    {
979
        s~\s+~~;
980
        Internal::MakeSymLink ("/bin/busybox", $_, '--NoDotDot'  );
981
    }
982
    close BBLINK;
983
 
984
    #
985
    #   May want to convert busybox.links into a .LINKS file and process
986
    #   it when we instantiate the file system
987
    #
988
 
989
}
990
 
991
#-------------------------------------------------------------------------------
992
# Function        : upgrade
993
#
994
# Description     : Insert day0 upgrade components
995
#
996
# Inputs          : None
997
#
998
# Returns         : Nothing
999
#
1000
sub upgrade
1001
{
1002
    Message ("Copy in day0 upgrade");
1003
    my $DAY0BIN="/afc/day-zero/bin";       #/day-zero
1004
 
1005
    ::CopyPackage ('bin',     "--Dest=$DAY0BIN", 'udp_broadcast' );
1006
    ::CopyPackage ('bin',     "--Dest=$DAY0BIN", 'udp_listen' );
1007
    ::CopyPackage ('scripts', "--Dest=$DAY0BIN", 'day-zero.conf' );
1008
    ::CopyPackage ('scripts', "--Dest=$DAY0BIN", 'day-zero.sh', 'day-zero' );
1009
 
1010
    #
1011
    #   Start Day-Zero Service
1012
    #   The service script is a part of the skeleton
1013
    #
1014
    ::AddInitScript ("day-zero"   , 95, 100-95, "--NoCopy" );
1015
}
1016
 
1017
#-------------------------------------------------------------------------------
1018
# Function        : dams
1019
#
1020
# Description     : Insert DAMS
1021
#                   Only sutable for single exe versions
1022
#
1023
# Inputs          : 
1024
#
1025
# Returns         : 
1026
#
1027
sub dams
1028
{
1029
    Message ("Copy in DAMS");
1030
    ::CopyPackage ('bin',     "--Dest=/afc/dams/bin", 'dams' );
1031
}
1032
 
1033
#-------------------------------------------------------------------------------
1034
# Function        : wirelesstools
1035
#
1036
# Description     : Insert wireless tools
1037
#                   This is a multi-call binary
1038
# Inputs          :
1039
#
1040
# Returns         : 
1041
#
1042
sub wirelesstools
1043
{
1044
    Message ("Copy in wireless tools");
1045
 
1046
    ::CopyPackage ('bin', 'ifrename'  , "--Dest=/sbin");
1047
    ::CopyPackage ('bin', 'iwconfig'  , "--Dest=/sbin");
1048
    ::CopyPackage ('bin', 'iwevent'   , "--Dest=/sbin");
1049
    ::CopyPackage ('bin', 'iwgetid'   , "--Dest=/sbin");
1050
    ::CopyPackage ('bin', 'iwlist'    , "--Dest=/sbin");
1051
    ::CopyPackage ('bin', 'iwpriv'    , "--Dest=/sbin");
1052
    ::CopyPackage ('bin', 'iwspy'     , "--Dest=/sbin");
1053
}
1054
 
1055
#-------------------------------------------------------------------------------
1056
# Function        : zd1211
1057
#
1058
# Description     : Copy in the zd1211 support files
1059
#
1060
# Inputs          : 
1061
#
1062
# Returns         : 
1063
#
1064
 
1065
sub zd1211
1066
{
1067
    Message ("Copy in zd1211 firmware");
1068
    ::CopyPkgDir  ( 'pkg/zd1211', '/lib/firmware/zd1211', '--FilterOut=READ*' );
1069
 
1070
    #
1071
    #   Install the start up script
1072
    #   This will be delivered by the kernel package
1073
    #
1074
    ::AddInitScript ("$opt_interfacedir/etc/zd1211", 41, 100-41 );
1075
}
1076
 
1077
#-------------------------------------------------------------------------------
1078
# Function        : kernelmodules
1079
#
1080
# Description     : Insert Kernel Modules
1081
#                   Note: The EMU flavour does not have any kernel modules (yet)
1082
#                          Allow for no files to be present or copied
1083
#
1084
# Inputs          : 
1085
#
1086
# Returns         : 
1087
#
1088
sub kernelmodules
1089
{
1090
    Message ("Copy in Kernel Modules");
1091
    CopyDir ( "${opt_interfacedir}/bin", "$WORK/lib/modules",
1092
                    'Flatten' => 1,
1093
                    'Match' => [ '*.ko' ],
1094
                    'Log' => 1,
1095
                     );
1096
}
1097
 
1098
#-------------------------------------------------------------------------------
1099
# Function        : e2fsprogs
1100
#
1101
# Description     : Insert e2fsprogs
1102
#                   Busybox 1.4.2 and later does not provide these utilities
1103
#                   so they have been built up.
1104
#
1105
# Inputs          :
1106
#
1107
# Returns         : 
1108
#
1109
sub e2fsprogs
1110
{
1111
    #
1112
    #   Only install the files that are needed
1113
    #
1114
    Message        ("Copy in e2fsprogs");
1115
    ::CopyPackage    ('pkg', "/etc/mke2fs.conf");
1116
    ::CopyPackage    ('pkg', "/sbin/fsck");
1117
    ::CopyPackage    ('pkg', "/sbin/tune2fs"   ,"e2label"   ,"findfs");
1118
    ::CopyPackage    ('pkg', "/sbin/mke2fs"    ,"mkfs.ext2" ,"mkfs.ext3");
1119
    ::CopyPackage    ('pkg', "/sbin/e2fsck"    ,"fsck.ext2" ,"fsck.ext3");
1120
    #::CopyPackage   ('pkg', "/sbin/badblocks");
1121
    #::CopyPackage   ('pkg', "/sbin/blkid");
1122
    #::CopyPackage   ('pkg', "/sbin/debugfs");
1123
    #::CopyPackage   ('pkg', "/sbin/dumpe2fs");
1124
    #::CopyPackage   ('pkg', "/sbin/logsave");
1125
    ::CopyPackage    ('pkg', "/sbin/resize2fs");
1126
}
1127
 
1128
#-------------------------------------------------------------------------------
1129
# Function        : compilerruntime
1130
#
1131
# Description     : Copy in the runtime shared libraries provided by the compiler
1132
#                       Many libraries are also symlinked
1133
#                       Need to ensure that the linkis copied
1134
#
1135
#                       Strip many ( but not all) of the libaries
1136
#                       Some are special
1137
# Inputs          : 
1138
#
1139
# Returns         : 
1140
#
1141
sub compilerruntime
1142
{
1143
    Message ("Copy in Compiler Shared Libaries");
1144
    my @slibs;
1145
    JatsCopy::CopyDir( $CROSSLIBS, "$WORK/lib",
1146
                            'Flatten' => 1,
1147
                            'NoSubDirs' => 1,
1148
                            'DuplicateLinks' => 1,
1149
                            'Match' => [ '*.so', '*.so.*[0-9]' ],
1150
                            'FileList' => \@slibs,
1151
                            );
1152
 
1153
 
1154
    foreach my $file (@slibs)
1155
    {
1156
        next if ( -d $file );
1157
        next if ( -l $file );
1158
        next if ( $file =~ m~libc.so$~ );
1159
        next if ( $file =~ m~libpthread.so$~ );
1160
        next if ( $file =~ m~libthread_db.*\.so~ );         # Needs symbols
1161
        Verbose ("Stripping: $file");
1162
        System ($CROSS_STRIP, $file );
1163
    }
1164
 
1165
    #
1166
    #   Copy in ldconfig
1167
    #
1168
    Message ("Copy in the ldconfig utility");
1169
    ::CopyFile ( "${CROSSEXE}/sbin/ldconfig", "/sbin" );
1170
}
1171
 
1172
#-------------------------------------------------------------------------------
1173
# Function        : grub
1174
#
1175
# Description     : Install grub related files, if requested by the user
1176
#
1177
# Inputs          : Options
1178
#                       --Menu=file             - Found locally
1179
#                       --Kernel=file           - Found in Bin
1180
#
1181
# Returns         : 
1182
#
1183
sub grub
1184
{
1185
    my $menu;
1186
    my $kernel;
1187
 
1188
    Message ("Installing Grub");
1189
 
1190
    #
1191
    #   Extract options
1192
    #
1193
    foreach ( @_ )
1194
    {
1195
        if ( m~^--Menu=(.+)~ ) {
1196
            $menu = $1;
1197
        } elsif ( m~^--Kernel=(.+)~ ) {
1198
            $kernel = $1;
1199
        } else {
1200
            Error ("Day0 Grub: Unknown option: $_");
1201
        }
1202
    }
1203
 
1204
    Error ("Day0 Grub: No Menu file specified") unless ( $menu );
1205
    Error ("Day0 Grub: No Kernel file specified") unless ( $kernel );
1206
 
1207
    ::CopyPackage ( 'pkg', '/boot/grub/grub');                     # Not really needed
1208
    ::CopyPackage ( 'pkg', '/boot/grub/stage1');                   # These are ..
1209
    ::CopyPackage ( 'pkg', '/boot/grub/stage2');
1210
    ::CopyPackage ( 'pkg', '/boot/grub/e2fs_stage1_5');
1211
 
1212
    #
1213
    #   Copy in the user specified boot related files
1214
    #
1215
    ::CopyFile   ( $menu,  '/boot/grub' );
1216
    ::CopyPackage ('bin', $kernel, '--Dest=/boot');
1217
 
1218
}
1219
 
1220
 
1221
 
1222
################################################################################
1223
################################################################################
1224
#
1225
#   Package to contain Internal functions
1226
#   Functions placed here are not available to the user in the user scripts
1227
#   They have been placed here simply to hide them from the user
1228
#
1229
#
1230
package Internal;
1231
 
1232
use strict;
1233
use warnings;
1234
 
1235
use File::Find;
1236
use JatsError;
1237
use FileUtils;
1238
 
1239
#-------------------------------------------------------------------------------
1240
# Function        : MakeSymLink
1241
#
1242
# Description     : Create a symlink - with error detection
1243
#
1244
# Inputs          : old_file    - Link Target
1245
#                                 Path to the link target
1246
#                                 If an ABS path is provided, the routine will
1247
#                                 attempt to create a relative link.
1248
#                   new_file    - Relative to the output work space
1249
#                                 Path to where the 'link' file will be created
1250
#                   Options     - Must be last
1251
#                                 --NoClean         - Don't play with links
1252
#                                 --NoDotDot        - Don't create symlinks with ..
1253
#
1254
# Returns         : Nothing
1255
#
1256
sub MakeSymLink
1257
{
1258
    my $no_clean;
1259
    my $no_dot;
1260
    my @args;
1261
 
1262
    #
1263
    #   Extract options
1264
    #
1265
    foreach ( @_ )
1266
    {
1267
        if ( m/^--NoClean/i ) {
1268
            $no_clean = 1;
1269
 
1270
        } elsif ( m/^--NoDotDot/i ) {
1271
            $no_dot = 1;
1272
 
1273
        } elsif ( m/^--/ ) {
1274
            Error ("MakeSymLink: Unknown option: $_");
1275
 
1276
        } else {
1277
            push @args, $_;
1278
        }
1279
    }
1280
 
1281
    my ($old_file, $new_file) = @args;
1282
 
1283
    my $tfile = $WORK . '/' . $new_file;
1284
    $tfile =~ s~//~/~;
1285
    Verbose ("Symlink $old_file -> $new_file" );
1286
 
1287
    #
1288
    #   Create the directory in which the link will be placed
1289
    #   Remove any existing file of the same name
1290
    #
1291
    my $dir = StripFileExt( $tfile );
1292
    mkdir $dir unless -d $dir;
1293
    unlink $tfile;
1294
 
1295
    #
1296
    #   Determine a good name of the link
1297
    #   Convert to a relative link in an attempt to prune them
1298
    #
1299
    my $sfile = $old_file;
1300
    unless ( $no_clean )
1301
    {
1302
        $sfile = CalcRelPath( StripFileExt( $new_file ), $old_file );
1303
        if ( $no_dot && $sfile =~ m~^../~ )
1304
        {
1305
            $sfile = $old_file;
1306
        }
1307
    }
1308
 
1309
    my $result = symlink $sfile, $tfile;
1310
    Error ("Cannot create symlink. $old_file -> $new_file") unless ( $result );
1311
}
1312
 
1313
#-------------------------------------------------------------------------------
1314
# Function        : LocateFile
1315
#
1316
# Description     : Locate a file within the interface directory
1317
#                   These files will have come from an external package
1318
#
1319
# Inputs          : $section            One of: bin, lib, pkg, scripts
1320
#                                       Will be translated into a suitable path
1321
#                   $file               Path to file
1322
#
1323
# Returns         : Full path to the file
1324
#                   Will return 'undef' if not found
1325
#                   The user must generate the error
1326
#
1327
sub LocateFile
1328
{
1329
    my ($section, $file) = @_;
1330
    my $base = "$opt_interfacedir/$section";
1331
 
1332
    unless ( -d $base )
1333
    {
1334
        Warning("LocateFile: Section not found: $section");
1335
        return undef;
1336
    }
1337
 
1338
    my @done;
1339
    my @parts = GetBuildParts ($opt_interfacedir, $opt_platform );
1340
    push @parts, '';
1341
    foreach my $type ( $opt_type, '' )
1342
    {
1343
        foreach my $subdir ( @parts )
1344
        {
1345
            my $sfile = "$base/$subdir$type/$file";
1346
            $sfile =~ s~//~/~g;
1347
            Verbose2("LocateFile: $sfile");
1348
            if ( -f $sfile )
1349
            {
1350
                unless ( @done )
1351
                {
1352
                    push @done, $sfile;
1353
                }
1354
            }
1355
        }
1356
    }
1357
 
1358
    if ( $#done > 0)
1359
    {
1360
        Warning ("LocateFile: Multiple instances of file found. Only first is used", @done);
1361
    }
1362
    return $done[0];
1363
}
1364
 
1365
#-------------------------------------------------------------------------------
1366
# Function        : LocateDebianFile
1367
#
1368
# Description     : Locate a debian file
1369
#                   Internal Function
1370
#
1371
#                   Scan packages for the Debian package specified
1372
#                   The user provides the base name of the package
1373
#                   A Debian Package name has several fields
1374
#                   These are:
1375
#                       1) Base Name - Provided by the user
1376
#                       2) Version - Version will be wildcarded
1377
#                       3) Architecture - Wildcarded. Uses bin/arch directory
1378
#                   
1379
#                   Expect to find Debian Packages in the bin/PLATFORM subdir
1380
#
1381
# Inputs          : Debian base name, complete with suboptions
1382
#
1383
# Returns         : Full path of the file
1384
#
1385
sub LocateDebianFile
1386
{
1387
    my ($arg, $arch, $product) = @_;
1388
    Verbose("LocateDebianFile: Processing: $arg");
1389
 
1390
    my @type = qw( P D );
1391
    my %debian_file_path;
1392
 
1393
    #
1394
    #   Extract sub-options
1395
    #       --Prod[uction]
1396
    #       --Debug
1397
    #       --Arch[itecture]=yyy
1398
    #
1399
    my ($base_name, @opts) = split( ',', $arg );
1400
    foreach ( @opts )
1401
    {
1402
        if ( m/^--Arch(.*)=(.+)/ ) {
1403
            $arch=$2;
1404
        } elsif ( m/^--Product=(.+)/ ) {
1405
            $product=$1;
1406
        } elsif ( m/^--Prod/ ) {
1407
            @type = 'P';
1408
        } elsif ( m/^--Debug/ ) {
1409
            @type = 'D';
1410
        }
1411
    }
1412
 
1413
    #
1414
    #   Create a list of products
1415
    #   ie: PRODUCT_ARCH
1416
    #
1417
    my @products;
1418
    push @products, $product . '_' . $arch if ( $product );
1419
    push @products, $arch;
1420
 
1421
    #
1422
    #   Scan all packages for the specified debian package
1423
    #
1424
    foreach my $package_dir ( $opt_interfacedir )
1425
    {
1426
        foreach my $type ( @type )
1427
        {
1428
            foreach my $prd ( @products )
1429
            {
1430
                foreach my $joiner ( qw(/ .) )
1431
                {
1432
                    my $dir = "$package_dir/bin$joiner$prd$type";
1433
                    Verbose("LocateDebianFile: Search in $dir");
1434
                    next unless ( -d $dir );
1435
                    my @files = glob ( "$dir/${base_name}_*.deb" );
1436
                    next unless ( @files );
1437
                    push @{$debian_file_path{$type}}, @files;
1438
                }
1439
            }
1440
        }
1441
    }
1442
 
1443
    Error ("Required Debain package not found: $base_name",) unless %debian_file_path;
1444
 
1445
    #
1446
    #   Select 'preferred' type of file
1447
    #   If we are doing a debug build, then prefer debug package
1448
    #   If not available then use any available
1449
    #
1450
    my @debian_file_path = @{$debian_file_path{$opt_type}};
1451
    if ( ! @debian_file_path )
1452
    {
1453
        foreach ( keys %debian_file_path )
1454
        {
1455
            push @debian_file_path,@{$debian_file_path{$_}};
1456
        }
1457
    }
1458
 
1459
    Error ("Multiple matching Debian Packages located", @debian_file_path)
1460
        if ( $#debian_file_path > 0 );
1461
 
1462
    return $debian_file_path[0];
1463
}
1464
 
1465
#-------------------------------------------------------------------------------
1466
# Function        : CalcRelPath
1467
#
1468
# Description     : Return the relative path to the current working directory
1469
#                   as provided in $Cwd
1470
#
1471
# Inputs          : $Cwd - Base dir
1472
#                   $base - Path to convert
1473
#
1474
# Returns         : Relative path from the $Cwd
1475
#
1476
sub CalcRelPath
1477
{
1478
    my ($Cwd, $base) = @_;
1479
 
1480
    my @base = split ('/', $base );
1481
    my @here = split ('/', $Cwd );
1482
    my $result;
1483
 
1484
    Debug("CalcRelPath: Source: $base");
1485
 
1486
    return $base unless ( $base =~ m~^/~ );
1487
 
1488
    #
1489
    #   Remove common bits from the head of both lists
1490
    #
1491
    while ( $#base >= 0 && $#here >= 0 && $base[0] eq $here[0] )
1492
    {
1493
        shift @base;
1494
        shift @here;
1495
    }
1496
 
1497
    #
1498
    #   Need to go up some directories from here and then down into base
1499
    #
1500
    $result = '../' x ($#here + 1);
1501
    $result .= join ( '/', @base);
1502
    $result = '.' unless ( $result );
1503
    $result =~ s~//~/~g;
1504
    $result =~ s~/$~~;
1505
 
1506
    Debug("CalcRelPath: Result: $result");
1507
    return $result;
1508
}
1509
 
1510
#-------------------------------------------------------------------------------
1511
# Function        : GetBuildParts
1512
#
1513
# Description     : Determine the 'parts' of the build for the current platform
1514
#                   This is complex information. It is held within the build.cfg
1515
#                   file.
1516
#
1517
# Inputs          : $interface_dir          - Path to the interface dir
1518
#                   $platform               - Platform to process
1519
#
1520
# Returns         : An array of platform parts
1521
#
1522
 
1523
#
1524
#   The following varaibles are "read" in from the build.cfg file
1525
#   In order to access them we need to declare them
1526
#
1527
our %ScmBuildPkgRules;
1528
our %BUILDPLATFORM_PARTS;
1529
 
1530
sub GetBuildParts
1531
{
1532
    my ($interface_dir, $platform) = @_;
1533
 
1534
    #
1535
    #   Tthe build.cfg file is within the interface directory
1536
    #
1537
    my $cfgfile = "$interface_dir/build.cfg";
1538
    Error ("Cannot find file: $cfgfile" ) unless ( -f $cfgfile );
1539
 
1540
    #
1541
    #   Include the build.cfg data
1542
    #
1543
    require ( $cfgfile );
1544
 
1545
    #
1546
    #   Extract the platform parts
1547
    #
1548
    if ( exists  $BUILDPLATFORM_PARTS{$platform})
1549
    {
1550
        return @{$BUILDPLATFORM_PARTS{$platform}};
1551
    }
1552
    else
1553
    {
1554
        Error ("Platform not found in build.cfg: $platform");
1555
    }
1556
}
1557
 
1558
#-------------------------------------------------------------------------------
1559
# Function        : FindFiles
1560
#
1561
# Description     : Locate files within a given dir tree
1562
#
1563
# Inputs          : $root           - Base of the search
1564
#                   $match          - Re to match
1565
#
1566
# Returns         : A list of files that match
1567
#
1568
my @FIND_LIST;
1569
my $FIND_NAME;
1570
 
1571
sub FindFiles
1572
{
1573
    my ($root, $match ) = @_;
1574
    Verbose2("FindFiles: Root: $root, Match: $match");
1575
 
1576
    #
1577
    #   Becareful of closure, Must use globals
1578
    #
1579
    @FIND_LIST = ();
1580
    $FIND_NAME = $match;
1581
    File::Find::find( \&find_files, $root);
1582
 
1583
    #
1584
    #   Find callback program
1585
    #
1586
    sub find_files
1587
    {
1588
        my $item =  $File::Find::name;
1589
        return if ( -d $_ );
1590
        return unless ( $_ =~ m~$FIND_NAME~ );
1591
        push @FIND_LIST, $item;
1592
    }
1593
    return @FIND_LIST;
1594
}
1595
 
1596
 
1597