Subversion Repositories DevTools

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
7323 dpurdie 1
########################################################################
2
# Copyright (c) VIX TECHNOLOGY (AUST) LTD
3
#
4
# Module name   : JatsLocatePkgFile.pm
5
# Module type   : Makefile system
6
# Compiler(s)   : Perl
7
# Environment(s): jats
8
#
9
# Description   : Package to simplify the process of locating one or more
10
#                 files with the JATS build environment.
11
#
12
#                 Specifically designed to assist in the creation of:
13
#                       Day0 file systems
14
#                       Debian Packages
15
#                       Deployable packages
16
#
17
#                 Intended to locate files in dependent packages
18
#                 Supports LinkPkgArchive and BuildPkgArchive
19
#
20
#                 Knows about the construction of programs and shared
21
#                 libraries as well as other special file types.
22
#
23
#                 Uses a set of options to identify the file
24
#                 The file specifier is of the form
25
#                       Name[,--Option]+
26
#
27
#                 Available Options are:
28
#                       --prog          - Name is a program
29
#                                         Search where programs are stored
30
#                                         Append the target specific suffix
31
#                       --bin           - Similar to --prog, but does not modify
32
#                                         the provided name.
33
#                       --deb           - Name is the base of a Debian Package
34
#                                         Searchs in BIN directories
35
#                       --lib           - Name is the base of a Shared Library
36
#                                         Searchs in LIB directories
37
#                       --dir=SubDir    - Search for Name in a subdir of the
38
#                                         dependent packages
39
#                       --pkg           - Search for Name in a pkg subdir
40
#                                         Limited by the current target
41
#                       --etc           - Same as --dir=etc
42
#                       --jar           - Same as --dir=jar
43
#                       --scripts       - Same as --dir=scripts
44
#
45
#                       --AllowMultiple - Allow multiple files
46
#
47
# Usage:
48
#
49
#   $Locator = JatsLocatePkgFile::New( Platform, 'P' );
50
#   $result = $Locator->LocateFile ('busybox,--prog');
51
#
52
#
53
#......................................................................#
54
 
55
require 5.008_002;
56
use strict;
57
use warnings;
58
 
59
package JatsLocatePkgFile;
60
 
61
use JatsError;
62
use JatsMakeConfig;
63
 
64
# automatically export what we need into namespace of caller.
65
use Exporter();
66
our (@ISA, @EXPORT);
67
@ISA         = qw(Exporter);
68
@EXPORT      = qw(
69
                    FileSet
70
                );
71
 
72
#
73
#   Hash of known file location specifications
74
#   Only allowed to have one in any one definition
75
#
76
my %LocSpec = (
77
    'prog'          => { code => \&searchProg },
78
    'bin'           => { code => \&searchBin },
79
    'deb'           => { code => \&searchDeb },
80
    'dir'           => { code => \&searchDir },
81
    'pkg'           => { code => \&searchPkg },
82
    'lib'           => { code => \&searchLib },
83
    'etc'           => { code => \&searchSimple, dir => 'etc' },
84
    'jar'           => { code => \&searchSimple, dir => 'jar'},
85
    'scripts'       => { code => \&searchSimple, dir => 'scripts'},
86
#    'thx'           => 1,
87
#    'jar'           => 1,
88
#    'local'         => 1,
89
#    'interface'     => 1,
90
);
91
 
92
#-------------------------------------------------------------------------------
93
# Function        : FileSet
94
#
95
# Description     : Create a new instance of a File Locator
96
#                   Used to provide the basic configuration of the target
97
#                   system
98
#
99
# Inputs          : None
100
#                   Useful information is prsent in the environment
101
#
102
#
103
# Returns         : Class Ref
104
#
105
sub FileSet
106
{
107
    Debug ("New JatsLocatePkgFile");
108
    my $self;
109
 
110
    #
111
    #   Load all the MakeFile generate information and  data structures
112
    #
113
    my $mi = JatsMakeConfigLoader::Load();
114
 
115
    #
116
    #   Document Class Variables
117
    #
118
    $self->{'platform'} = $mi->{'PLATFORM'};
119
    $self->{'type'}     = $mi->{'TYPE'};
120
    $self->{'cache'}    = undef;
121
 
122
    #
123
    #   Create a class
124
    #   Bless my self
125
    #
126
    bless ($self, __PACKAGE__);
127
 
128
    #
129
    #   Locate required entries
130
    #
131
    my @result;
132
    for my $entry ( @{$mi->GetDataItem('%ScmBuildPkgRules')} )
133
    {
134
        #
135
        #   If a BuildPkgArchive, then skip as its data will be embedded
136
        #   in the pseudo INTERFACE package
137
        #
138
        next if ( ($entry->{'TYPE'} eq 'build' ) );
139
        push @result, $entry->{'ROOT'};
140
    }
141
    $self->{'BuildPaths'} = \@result;
142
    $self->{'BuildParts'} = $mi->GetDataItem('%BUILDPLATFORM_PARTS');
143
 
144
    $self->{'a'}    =  $mi->GetDataItem('$a');
145
    $self->{'exe'}  =  $mi->GetDataItem('$exe');
146
    $self->{'so'}   =  $mi->GetDataItem('$so');
147
 
148
#    DebugDumpData(__PACKAGE__, $self );
149
    return $self;
150
}
151
 
152
#-------------------------------------------------------------------------------
153
# Function        : LocateFile
154
#
155
# Description     : Locate a file as specified by a user description
156
#
157
# Inputs          : $self                   - Instance Data
158
#                   $fspec                  - A file specification
159
#
160
# Returns         : A list of files that match
161
#                   May not return on error
162
#
163
sub LocateFile
164
{
165
    my $self = shift;
166
    my ($fspec) = @_;
167
    my $opts;
168
    my $mode;
169
 
170
    #
171
    #   Split the file spec into bits
172
    #   Extract options and the base file name
173
    #       Create a hash of options
174
    #       Convert options to lowercase
175
    #       Extract any assignments
176
    #       Treat --Flag as --Flag=1
177
    #
178
    $self->{'uspec'} = $fspec;
179
    while ( $fspec =~ m~^(.*),--(.*?)(=(.*?))?,*$~ )
180
    {
181
        $fspec = $1;
182
 
183
        my $opt = lc($2);
184
        $opts->{$opt} = defined($3) ? $4 : 1;
185
 
186
        $mode = $LocSpec{$opt}
187
            if ( exists $LocSpec{$opt} )
188
    }
189
 
190
    #
191
    #   Save the remainder as the filename
192
    #   It may not exist
193
    #
194
    $opts->{'file'} = $fspec;
195
    $opts->{'Mode'} = $mode;
196
 
197
#    DebugDumpData("File", $opts);
198
 
199
    #
200
    #   Dispatch to a suitable processing routine
201
    #
202
    if ( $mode )
203
    {
204
        if ( $mode->{'code'} )
205
        {
206
 
207
            my @result = ( $mode->{'code'}( $self, $opts ) );
208
print "-----Files found: $#result\n";            
209
            if ( ! $opts->{'allowmultiple'} )
210
            {
211
                Error ("Mutliple Files found: $self->{'uspec'}" )
212
                    if ( $#result > 1 );
213
            }
214
            return wantarray ? @result : $result[0];
215
        }
216
        DebugDumpData("File", $opts);
217
        Error ("Unknown search method: @_");
218
    }
219
    else
220
    {
221
        #
222
        #   No Mode specified
223
        #   Must be a local file
224
        #
225
        my $ufile = $opts->{'file'};
226
        return $ufile
227
            if ( -f $ufile );
228
        return undef;
229
    }
230
}
231
 
232
#-------------------------------------------------------------------------------
233
# Function        : searchLib
234
#
235
# Description     : The user is looking for a shared library file
236
#                   It will have a specific extension
237
#                   It will be in one of the 'lib' directories known to JATS
238
#
239
#                   Current Limitations:
240
#                       Does not perform Unix Lib Prefix
241
#                       Does not handle Name.version.so
242
#                       Does not handle 'so' Name and 'real' name pairs
243
#
244
#
245
# Inputs          : $self                   - Instance Data
246
#                   $opts                   - Options Hash
247
#
248
# Returns         : 
249
#
250
sub searchLib
251
{
252
    my ($self, $opts) = @_;
253
 
254
    my $ufile = $opts->{'file'};
255
    my $ext =  $self->{so} ? '.' . $self->{a} : '';
256
    my @results;
257
    foreach my $dir ( @{ LibDirs($self) } )
258
    {
259
        foreach  ( glob ( "$dir/*") )
260
        {
261
            foreach my $type ( $self->{'type'}, '' )
262
            {
263
                push @results, $_  if ( $_ =~ "/$ufile$type$ext\$" );
264
            }
265
        }
266
 
267
#        foreach my $type ( $self->{'type'}, '' )
268
#        {
269
#            my $file = "$dir/$ufile" . $type . $ext;
270
#            push @results, $file
271
#                if ( -f $file );
272
#            }
273
    }
274
    return @results;
275
}
276
 
277
 
278
#-------------------------------------------------------------------------------
279
# Function        : searchProg
280
#
281
# Description     : The user is looking for a program file
282
#                   It will have a specific extension
283
#                   It will be in one of the 'Bin' directories known to JATS
284
#
285
# Inputs          : $self                   - Instance Data
286
#                   $opts                   - Options Hash
287
#
288
# Returns         : 
289
#
290
sub searchProg
291
{
292
    my ($self, $opts) = @_;
293
 
294
    my $ufile = $opts->{'file'} . $self->{exe};
295
    my @results;
296
    foreach my $dir ( @{ BinDirs($self) } )
297
    {
298
        foreach  ( glob ( "$dir/*") )
299
        {
300
            push @results, $_  if ( $_ =~ "/$ufile\$" );
301
        }
302
    }
303
    return @results;
304
 
305
#    my $ufile = $opts->{'file'} . $self->{exe};
306
#    foreach my $dir ( @{ BinDirs($self) } )
307
#    {
308
#        my $file = "$dir/$ufile";
309
#        return $file
310
#            if ( -f $file );
311
#    }
312
#    return undef;
313
}
314
 
315
#-------------------------------------------------------------------------------
316
# Function        : searchBin
317
#
318
# Description     : The user is looking for a program file
319
#                   It will be in one of the 'Bin' directories known to JATS
320
#
321
# Inputs          : $self                   - Instance Data
322
#                   $opts                   - Options Hash
323
#
324
# Returns         : 
325
#
326
sub searchBin
327
{
328
    my ($self, $opts) = @_;
329
 
330
    my $ufile = $opts->{'file'};
331
    my @results;
332
    foreach my $dir ( @{ BinDirs($self) } )
333
    {
334
        foreach  ( glob ( "$dir/*") )
335
        {
336
            push @results, $_  if ( $_ =~ "/$ufile\$" );
337
        }
338
    }
339
    return @results;
340
}
341
 
342
 
343
#-------------------------------------------------------------------------------
344
# Function        : searchDeb
345
#
346
# Description     : The user is looking for a Debian Package
347
#                   It will have a specific extension
348
#                   It will be in one of the 'Bin' directories known to JATS
349
#
350
# Inputs          : $self                   - Instance Data
351
#                   $opts                   - Options Hash
352
#
353
# Returns         : 
354
#
355
sub searchDeb
356
{
357
    my ($self, $opts) = @_;
358
 
359
    foreach my $dir ( @{ BinDirs($self) } )
360
    {
361
        if ( my @files = glob ( "$dir/$opts->{file}_*.deb" ) )
362
        {
363
            return $files[0];
364
        }
365
    }
366
    return undef;
367
}
368
 
369
#-------------------------------------------------------------------------------
370
# Function        : searchDir
371
#
372
# Description     : The user is looking for a file in a package subdir
373
#                   It will be in one of the package directories
374
#
375
# Inputs          : $self                   - Instance Data
376
#                   $opts                   - Options Hash
377
#
378
# Returns         : 
379
#
380
sub searchDir
381
{
382
    my ($self, $opts) = @_;
383
 
384
    my $ufile = $opts->{'file'};
385
    foreach my $dir ( @{ MiscDirs($self, $opts->{'dir'}) } )
386
    {
387
        my $file = "$dir/$ufile";
388
        return $file
389
            if ( -f $file );
390
    }
391
    return undef;
392
}
393
 
394
#-------------------------------------------------------------------------------
395
# Function        : searchSimple
396
#
397
# Description     : The user is looking for a file in known subdir subdir
398
#                   It will be in one of the package directories
399
#
400
# Inputs          : $self                   - Instance Data
401
#                   $opts                   - Options Hash
402
#
403
# Returns         : 
404
#
405
sub searchSimple
406
{
407
    my ($self, $opts) = @_;
408
 
409
    my $mode = $opts->{'Mode'}{'dir'};
410
    Error ("JatsLocatePkgFile. searchSimple. Internal Error. No 'dir' configured'",
411
            "Entry: $self->{'uspec'}") unless ( $mode );
412
 
413
    $opts->{'dir'} = $mode;
414
    return searchDir( $self, $opts );
415
}
416
 
417
#-------------------------------------------------------------------------------
418
# Function        : searchPkg
419
#
420
# Description     : The user is looking for a file in a package pkg subdir
421
#                   It will be in one of the package directories
422
#
423
# Inputs          : $self                   - Instance Data
424
#                   $opts                   - Options Hash
425
#
426
# Returns         : 
427
#
428
sub searchPkg
429
{
430
    my ($self, $opts) = @_;
431
 
432
    my $ufile = $opts->{'file'};
433
    foreach my $dir ( @{ PkgDirs($self) } )
434
    {
435
        my $file = "$dir/$ufile";
436
        return $file
437
            if ( -f $file );
438
    }
439
    return undef;
440
}
441
 
442
#-------------------------------------------------------------------------------
443
# Function        : BinDirs
444
#
445
# Description     : Return an array of directories to search for Bin files
446
#                   Cache results for future use
447
#
448
#                   Bin dirs are used to hold:
449
#                       Programs
450
#                       Debian Packages
451
#                       File System Images
452
#
453
#                   The directory is named after a platform and will have
454
#                   a P or D suffix
455
#
456
#                   Template:       {BASE}/bin/{PLATFORM}{TYPE}
457
#                   Compatability:  {BASE}/bin.{PLATFORM}{TYPE}
458
#                                   {BASE}/bin/bin.{PLATFORM}{TYPE}
459
#
460
# Inputs          : $self                   - Instance Data
461
#
462
# Returns         : An Array
463
#
464
sub BinDirs
465
{
466
    my $self = shift;
467
    #
468
    #   Return cached results
469
    #
470
    unless ( $self->{'cache'}{'bin'} )
471
    {
472
        #
473
        #   Create an array of location to search
474
        #
475
        my @dirs;
476
        foreach my $base ( @{$self->{'BuildPaths'}} )
477
        {
478
            foreach my $type ( $self->{'type'}, '' )
479
            {
480
                foreach my $subdir ( @{$self->{'BuildParts'}} )
481
                {
482
                    my $dir = "$base/bin/$subdir$type";
483
#print "----Try : $dir\n";
484
                    push @dirs, $dir if ( -d $dir );
485
                }
486
            }
487
        }
488
        $self->{'cache'}{'bin'} = \@dirs;
489
    }
490
    return $self->{'cache'}{'bin'}
491
}
492
 
493
#-------------------------------------------------------------------------------
494
# Function        : LibDirs
495
#
496
# Description     : Return an array of directories to search for Lib files
497
#                   Cache results for future use
498
#
499
#                   Lib dirs are used to hold:
500
#                       Shared Libraries
501
#                       Static Libraries
502
#
503
#                   The file name should have an embedded type (P or D)
504
#
505
#                   Template:       {BASE}/lib/{PLATFORM}
506
#                   Compatability:  {BASE}/lib/{PLATFORM}{TYPE}
507
#                                   {BASE}/lib.{PLATFORM}{TYPE}
508
#                                   {BASE}/lib/lib.{PLATFORM}{TYPE}
509
#
510
# Inputs          : $self                   - Instance Data
511
#
512
# Returns         : An Array
513
#
514
sub LibDirs
515
{
516
    my $self = shift;
517
    #
518
    #   Return cached results
519
    #
520
    unless ( $self->{'cache'}{'lib'} )
521
    {
522
        #
523
        #   Create an array of location to search
524
        #
525
        my @dirs;
526
        foreach my $base ( @{$self->{'BuildPaths'}} )
527
        {
528
            foreach my $type ( $self->{'type'}, '' )
529
            {
530
                foreach my $subdir ( @{$self->{'BuildParts'}})
531
                {
532
                    my $dir = "$base/lib/$subdir$type";
533
#print "----Try : $dir\n";
534
                    push @dirs, $dir if ( -d $dir );
535
                }
536
            }
537
        }
538
        $self->{'cache'}{'lib'} = \@dirs;
539
    }
540
    return $self->{'cache'}{'lib'}
541
}
542
 
543
#-------------------------------------------------------------------------------
544
# Function        : PkgDirs
545
#
546
# Description     : Return an array of directories to search for Pkg files
547
#                   Cache results for future use
548
#
549
#                   pkg dirs are used to contain foreign subdirectory trees
550
#                   Typically used to transparently transfer 3rd parts software
551
#
552
#                   There are two forms of pkg dir
553
#                   Both are not supported within the same package
554
#
555
#                   Form-1
556
#                   Template:       {BASE}/pkg
557
#
558
#                   Form-2
559
#                   Template:       {BASE}/pkg.{PLATFORM}
560
#                   Template:       {BASE}/pkg.{MACHTYPE}
561
#
562
#                   Currently NOT a very good pkg searcher
563
#                   It does not handle pkg/pkg.MACHTYPE dirs
564
#
565
# Inputs          : $self                   - Instance Data
566
#
567
# Returns         : An Array
568
#
569
sub PkgDirs
570
{
571
    my $self = shift;
572
    #
573
    #   Return cached results
574
    #
575
    unless ( $self->{'cache'}{'pkg'} )
576
    {
577
        #
578
        #   Create an array of location to search
579
        #
580
        my @dirs;
581
        foreach my $base ( @{$self->{'BuildPaths'}} )
582
        {
583
            next unless ( -d "$base/pkg" );
584
            foreach my $subdir ( @{$self->{'BuildParts'}} )
585
            {
586
                my $dir = "$base/pkg/$subdir";
587
#print "----Try : $dir\n";
588
                push @dirs, $dir if ( -d $dir );
589
            }
590
 
591
            unless ( @dirs )
592
            {
593
                push @dirs, $base;
594
            }
595
 
596
        }
597
        $self->{'cache'}{'pkg'} = \@dirs;
598
    }
599
    return $self->{'cache'}{'pkg'}
600
}
601
 
602
#-------------------------------------------------------------------------------
603
# Function        : MiscDirs
604
#
605
# Description     : Return an array of directories to search for Misc files
606
#                   Cache results for future use
607
#
608
#                   Misc dirs are used to contains files of known types
609
#                   Normally a flat directory structure
610
#                   No 'type' information
611
#
612
#                   Template:   {BASE}/{DIR}
613
#
614
#                   Used for dirs that are not special, like the Bin and Lib
615
#
616
# Inputs          : $self                   - Instance Data
617
#                   $root                   - Base of the section
618
#
619
# Returns         : An Array
620
#
621
sub MiscDirs
622
{
623
 
624
    my ($self, $root) = @_;
625
 
626
    #
627
    #   Clean up the user path
628
    #   Remove leading, trailing and multiple /
629
    #
630
    $root =~ s~/+~/~g;
631
    $root =~ s~^/~~;
632
    $root =~ s~/$~~;
633
 
634
    #
635
    #   Return cached results
636
    #
637
    unless ( $self->{'cache'}{$root} )
638
    {
639
        #
640
        #   Create an array of location to search
641
        #
642
        my @dirs;
643
        foreach my $base ( @{$self->{'BuildPaths'}} )
644
        {
645
            my $dir = "$base/$root";
646
#print "----Try : $dir\n";
647
            push @dirs, $dir if ( -d $dir );
648
        }
649
        $self->{'cache'}{$root} = \@dirs;
650
    }
651
    return $self->{'cache'}{$root}
652
}
653
 
654
 
655
#sub DESTROY
656
#{
657
#    DebugDumpData(__PACKAGE__, @_);
658
#}
659
1;
660
 
661
 
662