Subversion Repositories DevTools

Rev

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

Rev Author Line No. Line
407 dpurdie 1
########################################################################
2
# Copyright (C) 2007 ERG Limited, All rights reserved
3
#
4
# Module name   : jats.sh
5
# Module type   : Makefile system
6
# Compiler(s)   : n/a
7
# Environment(s): jats
8
#
9
# Description   : This program is invoked by the MakeDebianPackage
10
#                 directive, that is a part of this package
11
#
12
#                 The program will use a user-provided script in order
13
#                 to create a Debian Package.
14
#
15
#                 The user script may call a number of directives in order to
16
#                 construct an image of the package being installed.
17
#
18
#                 The script specifies Debian configuration scaripts that
19
#                 will be embedded in the package.
20
#
21
#                 This program will:
22
#                   Construct a filesystem image under control of the directives
23
#                   within the user script
24
#
25
#                   Massage the Debian control file
26
#
27
#                   Create a Debian Package
28
#
29
#                   Transfer it to the users 'BIN' directory, where it is
30
#                   available to be packaged.
31
#
32
#                 Summary of directives available to the user-script:
33
#                       AddInitScript           - Add an init script
34
#                       CatFile                 - Append to a file
35
#                       CopyDir                 - Copy directory tree
36
#                       CopyFile                - Copy a file
37
#                       CopyBinFile             - Copy an executable file
38
#                       CopyLibFile             - Copy a library file
39
#                       CreateDir               - Create a directory
40
#                       DebianFiles             - Specify control and script files
41
#                       EchoFile                - Place text into a file
42
#                       MakeSymLink             - Create a symbolic link
43
#                       PackageDescription      - Specify the package description
44
#                       SetFilePerms            - Set file permissions
45
#                       SetVerbose              - Control progress display
46
#                       IsProduct               - Flow control
47
#                       IsPlatform              - Flow control
48
#                       IsTarget                - Flow control
49
#
50
#                 Thoughts for expansion:
51
#                       ConvertFile             - Option to convert file(s) to Unix Text
52
#                       ReplaceTags             - Replace Tags on target file
53
#                       SrcDir                  - Extend path for resolving local files
54
#
55
#                   Less used:
56
#                        ExpandLinkFiles        - Expand .LINK files
57
#
58
#                   Internal Use:
59
#                        FindFiles              - Find a file
60
#                        ResolveFile            - Resolve a 'local' source file
61
#                        
62
#......................................................................#
63
 
411 dpurdie 64
require 5.006_001;
407 dpurdie 65
use strict;
66
use warnings;
67
 
68
use Getopt::Long;
69
use File::Path;
70
use File::Copy;
71
use File::Find;
72
use JatsSystem;
73
use FileUtils;
74
use JatsError;
75
use ReadBuildConfig;
423 dpurdie 76
use JatsCopy ();                            # Don't import anything
407 dpurdie 77
 
78
#
79
#   Globals
80
#
425 dpurdie 81
my $DebianWorkDirBase;                      # Workspace
407 dpurdie 82
my $DebianWorkDir;                          # Dir to create file system image within
83
 
84
#
85
#   Command line options
86
#
87
my $opt_debug   = $ENV{'GBE_DEBUG'};        # Allow global debug
88
my $opt_verbose = $ENV{'GBE_VERBOSE'};      # Allow global verbose
89
my $opt_vargs;                              # Verbose arg
90
my $opt_help = 0;
91
my $opt_manual = 0;
92
my $opt_clean = 0;
93
my $opt_platform;
94
my $opt_type;
95
my $opt_buildname;
96
my $opt_buildversion;
97
my $opt_interfacedir;
98
my $opt_target;
99
my $opt_product;
100
my $opt_package_script;
101
my $opt_interfaceincdir;
102
my $opt_interfacelibdir;
103
my $opt_interfacebindir;
104
my $opt_libdir;
105
my $opt_bindir;
106
my $opt_localincdir;
107
my $opt_locallibdir;
108
my $opt_localbindir;
109
my $opt_pkgdir;
110
my $opt_pkglibdir;
111
my $opt_pkgbindir;
112
my $opt_pkgpkgdir;
113
my $opt_output;
417 dpurdie 114
my $opt_name;
407 dpurdie 115
 
116
#
117
#   Options derived from script directives
118
#
119
my $opt_control = '';
120
my $opt_prerm = '';
121
my $opt_postrm = '';
122
my $opt_preinst = '';
123
my $opt_postinst = '';
124
my $opt_description;
125
 
415 dpurdie 126
#
127
#   Globals
128
#
129
my @ResolveFileList;                    # Cached Package File List
130
my @ResolveBinFileList;                 # Cached PackageBin File List
131
my @ResolveLibFileList;                 # Cached PackageLib File List
407 dpurdie 132
 
133
#-------------------------------------------------------------------------------
134
# Function        : Main Entry point
135
#
136
# Description     : This function will be called when the package is initialised
137
#                   Extract arguments from the users environment
138
#
139
#                   Done here to greatly simplify the user script
140
#                   There should be no junk in the user script - keep it simple
141
#
142
# Inputs          :
143
#
144
# Returns         : 
145
#
146
main();
147
sub main
148
{
149
    my $result = GetOptions (
150
                "verbose:s"         => \$opt_vargs,
151
                "clean"             => \$opt_clean,
152
                "Type=s"            => \$opt_type,
153
                "BuildName=s"       => \$opt_buildname,
154
                "BuildVersion=s"    => \$opt_buildversion,
155
                "Platform=s"        => \$opt_platform,
156
                "Target=s"          => \$opt_target,
157
                "Product=s"         => \$opt_product,
158
                "DebianPackage=s"   => \$opt_package_script,
159
                "InterfaceDir=s"    => \$opt_interfacedir,
160
                "InterfaceIncDir=s" => \$opt_interfaceincdir,
161
                "InterfaceLibDir=s" => \$opt_interfacelibdir,
162
                "InterfaceBinDir=s" => \$opt_interfacebindir,
163
                "LibDir=s"          => \$opt_libdir,
164
                "BinDir=s"          => \$opt_bindir,
165
                "LocalIncDir=s"     => \$opt_localincdir,
166
                "LocalLibDir=s"     => \$opt_locallibdir,
167
                "LocalBinDir=s"     => \$opt_localbindir,
168
                "PackageDir=s"      => \$opt_pkgdir,
169
                "PackageLibDir=s"   => \$opt_pkglibdir,
170
                "PackageBinDir=s"   => \$opt_pkgbindir,
171
                "PackagePkgDir=s"   => \$opt_pkgpkgdir,
172
                "Output=s"          => \$opt_output,
417 dpurdie 173
                "Name=s"            => \$opt_name,
407 dpurdie 174
    );
175
 
176
    $opt_verbose++ unless ( $opt_vargs eq '@' );
177
 
178
    ErrorConfig( 'name'    => 'DebianUtils',
179
                 'verbose' => $opt_verbose,
180
                 'debug'   => $opt_debug );
181
 
182
    #
183
    #   Init the FileSystem Uiltity interface
184
    #
185
    InitFileUtils();
186
 
187
    #
188
    #   Ensure that we have all required options
189
    #
190
    Error ("Platform not set")                  unless ( $opt_platform );
191
    Error ("Type not set")                      unless ( $opt_type );
192
    Error ("BuildName not set")                 unless ( $opt_buildname );
193
    Error ("BuildVersion not set")              unless ( $opt_buildversion );
194
    Error ("InterfaceDir not set")              unless ( $opt_interfacedir );
195
    Error ("Target not set")                    unless ( $opt_target );
196
    Error ("Product not set")                   unless ( $opt_product );
197
    Error ("DebianPackage not set")             unless ( $opt_package_script );
198
    Error ("Ouput File not set")                unless ( $opt_output );
417 dpurdie 199
    Error ("Build Name not set")                unless ( $opt_name );
407 dpurdie 200
 
201
    #
202
    #   Clean up the build name
203
    #   Match any work done in the MakeDebianPackage directive
204
    #
205
    $opt_buildname =~ s~_~-~g;
206
 
207
    #
208
    #   Read in relevent config information
209
    #
210
    ReadBuildConfig ($opt_interfacedir, $opt_platform, '--NoTest' );
211
 
212
    #
213
    #   Build the package image in a directory based on the target being created
214
    #
425 dpurdie 215
    $DebianWorkDirBase = "$opt_platform$opt_type.image";
216
    $DebianWorkDir = "$DebianWorkDirBase/$opt_name";
407 dpurdie 217
 
218
    #
219
    #   Configure the System command to fail on any error
220
    #
221
    SystemConfig ( ExitOnError => 1 );
222
 
223
    #
224
    #   Extract the 'name' of the package from the output path
225
    #   Display purposes only
226
    #
227
    my $DebianPkgName = StripDirExt($opt_output);
228
 
229
    #
230
    #   Display variables used
231
    #
232
    Message    "=Building Debian Package =============================================";
417 dpurdie 233
    Message    "Build $opt_name";
407 dpurdie 234
    Message    "       Package: $opt_buildname";
235
    Message    "       Version: $opt_buildversion";
236
    Message    "  Building for: $opt_platform, $opt_target";
237
    Message    "       Product: $opt_product";
238
    Message    "          Type: $opt_type";
239
    Verbose    "       Verbose: $opt_verbose";
240
    Verbose    "  InterfaceDir: $opt_interfacedir";
241
    Message    "       Package: $DebianPkgName";
242
    Message    "======================================================================";
243
 
244
    #
245
    #   Perform Clean up
246
    #   Invoked during "make clean" or "make clobber"
247
    #
248
    if ( $opt_clean )
249
    {
250
        Message ("Remove packaging directory: $DebianWorkDir");
425 dpurdie 251
 
252
        #
253
        #   Remove the directory for this package
254
        #   Remove the general work dir - if all packages have been cleaned
255
        #
407 dpurdie 256
        rmtree( $DebianWorkDir );
425 dpurdie 257
        rmdir( $DebianWorkDirBase );
407 dpurdie 258
        rmtree ($opt_output) if ( -f $opt_output );
259
        exit;
260
    }
261
 
262
    #
263
    #   Clean  out the WORK directory
264
    #   Always start with a clean slate
265
    #
266
    #   Ensure that the base of the directory tree does not have 'setgid'
267
    #       This will upset the debian packager
268
    #       This may be an artifact from the users directory and not expected
269
    #
270
    rmtree( $DebianWorkDir );
271
    mkpath( $DebianWorkDir );
272
 
273
    my $perm = (stat $DebianWorkDir)[2] & 0777;
274
    chmod ( $perm & 0777, $DebianWorkDir );
275
 
276
    #
277
    #   Invoke the user script to do the hard work
278
    #
279
    do $opt_package_script;
280
 
281
    #
282
    #   Complete the building of the package
283
    #
284
    BuildDebianPackage ();
285
    Message ("Created Debian Package");
286
}
287
 
288
#-------------------------------------------------------------------------------
289
# Function        : BuildDebianPackage
290
#
291
# Description     : This function will create the Debian Package
292
#                   and transfer it to the target directory
293
#
294
# Inputs          : None
295
#
296
# Returns         : Nothing
297
#
298
sub BuildDebianPackage
299
{
300
    Error ("BuildDebianPackage: No Control File or Package Description")
301
        unless ( $opt_control || $opt_description );
302
 
303
    #
304
    #   Convert the FileSystem Image into a Debian Package
305
    #       Insert Debian control files
306
    #
307
    Verbose ("Copy in the Debian Control Files");
308
    mkdir ( "$DebianWorkDir/DEBIAN" );
309
 
310
    CopyFile ( $opt_prerm,    "/DEBIAN", "prerm" )    if $opt_prerm;
311
    CopyFile ( $opt_postrm,   "/DEBIAN", "postrm" )   if $opt_postrm;
312
    CopyFile ( $opt_preinst,  "/DEBIAN", "preinst" )  if $opt_preinst;
313
    CopyFile ( $opt_postinst, "/DEBIAN", "postinst" ) if $opt_postinst;
314
 
315
    UpdateControlFile ($opt_control );
316
    System ( 'chmod', '-R', 'a+rx', "$DebianWorkDir/DEBIAN" );
317
    System ( 'build_dpkg.sh', '-b', $DebianWorkDir);
318
    System ( 'mv', '-f', "$DebianWorkDir.deb", $opt_output );
319
 
320
    System ("build_dpkg.sh", '-I', $opt_output) if (IsVerbose(1));
321
 
322
}
323
 
324
#-------------------------------------------------------------------------------
325
# Function        : UpdateControlFile
326
#
327
# Description     : Update the Debian 'control' file to fix up varoius fields
328
#                   within the file.
329
#
330
#                   If the files has not been specified, then a basic control
331
#                   file will be provided.
332
#
333
#                   This routine knows where the control file will be placed
334
#                   within the output work space.
335
#
336
# Inputs          : $src            - Path to source file
337
#                   Uses global variables
338
#
339
# Returns         : Nothing
340
#
341
sub UpdateControlFile
342
{
343
    my($src) = @_;
344
    my $dst = "$DebianWorkDir/DEBIAN/control";
345
 
346
    unless ( $src )
347
    {
348
        CreateControlFile();
349
        return;
350
    }
351
 
352
    Verbose ("UpdateControlFile: $dst" );
353
    $src = ResolveFile( 0, $src );
354
 
355
    open (SF, '<', $src) || Error ("UpdateControlFile: Cannot open $src");
356
    open (DF, '>', $dst) || Error ("UpdateControlFile: Cannot create:$dst");
357
    while ( <SF> )
358
    {
359
        s~\s*$~~;
360
        if ( m~^Package:~ ) {
361
            $_ = "Package: $opt_buildname";
362
 
363
        } elsif ( m~^Version:~ ) {
364
            $_ = "Version: $opt_buildversion";
365
 
366
        } elsif ( m~^Architecture:~ ) {
367
            $_ = "Architecture: $opt_platform";
368
 
369
        } elsif ( $opt_description && m~^Description:~ ) {
370
            $_ = "Description: $opt_description";
371
        }
372
        print DF $_ , "\n";
373
    }
374
    close (SF);
375
    close (DF);
376
}
377
 
378
#-------------------------------------------------------------------------------
379
# Function        : CreateControlFile
380
#
381
# Description     : Craete a basic debian control file
382
#
383
# Inputs          : Uses global variables
384
#
385
# Returns         : 
386
#
387
sub CreateControlFile
388
{
389
    my $dst = "$DebianWorkDir/DEBIAN/control";
390
 
391
    Verbose ("CreateControlFile: $dst" );
392
 
393
    open (DF, '>', $dst) || Error ("CreateControlFile: Cannot create:$dst");
394
    print DF "Package: $opt_buildname\n";
395
    print DF "Version: $opt_buildversion\n";
396
    print DF "Section: main\n";
397
    print DF "Priority: standard\n";
398
    print DF "Architecture: $opt_platform\n";
399
    print DF "Essential: yes\n";
400
    print DF "Maintainer: ERG\n";
401
    print DF "Description: $opt_description\n";
402
    close (DF);
403
}
404
 
405
#-------------------------------------------------------------------------------
406
# Function        : SetVerbose
407
#
408
# Description     : Set the level of verbosity
409
#                   Display activity
410
#
411
# Inputs          : Verbosity level
412
#                       0 - Use makefile verbosity (Default)
413
#                       1..2
414
#
415
# Returns         : 
416
#
417
sub SetVerbose
418
{
419
    my ($level) = @_;
420
 
421
    $level = $opt_verbose unless ( $level );
422
    $opt_verbose = $level;
423
    ErrorConfig( 'verbose' => $level);
424
}
425
 
426
 
427
#-------------------------------------------------------------------------------
428
# Function        : DebianFiles
429
#
430
# Description     : Name Debian builder control files
431
#                   May be called multiple times
432
#
433
# Inputs          : Options
434
#                       --Control=file
435
#                       --PreRm=file
436
#                       --PostRm=file
437
#                       --PreInst=file
438
#                       --PostInst=file
439
#
440
# Returns         : Nothing
441
#
442
sub DebianFiles
443
{
444
    #
445
    #   Exctact names
446
    #
447
    Verbose ("Specify Debian Control Files and Scripts");
448
    foreach  ( @_ )
449
    {
450
        if ( m/^--Control=(.+)/ ) {
451
            $opt_control = $1;
452
 
453
        } elsif ( m/^--PreRm=(.+)/ ) {
454
            $opt_prerm = $1;
455
 
456
        } elsif ( m/^--PostRm=(.+)/ ) {
457
            $opt_postrm = $1;
458
 
459
        } elsif ( m/^--PreInst=(.+)/ ) {
460
            $opt_preinst  = $1;
461
 
462
        } elsif ( m/^--PostInst=(.+)/ ) {
463
            $opt_postinst = $1;
464
 
465
        } else {
466
            Error ("DebianFiles: Unknown option: $_");
467
        }
468
    }
469
}
470
 
471
#-------------------------------------------------------------------------------
472
# Function        : PackageDescription
473
#
474
# Description     : Specify the Package Description
475
#                   Keep it short
476
#
477
# Inputs          : $description
478
#
479
# Returns         : 
480
#
481
sub PackageDescription
482
{
483
    ($opt_description) = @_;
484
}
485
 
486
#-------------------------------------------------------------------------------
487
# Function        : MakeSymLink
488
#
489
# Description     : Create a symlink - with error detection
490
#
491
# Inputs          : old_file    - Link Target
492
#                                 Path to the link target
493
#                                 If an ABS path is provided, the routine will
494
#                                 attempt to create a relative link.
495
#                   new_file    - Relative to the output work space
496
#                                 Path to where the 'link' file will be created
497
#                   Options     - Must be last
498
#                                 --NoClean         - Don't play with links
499
#                                 --NoDotDot        - Don't create symlinks with ..
500
#
501
# Returns         : Nothing
502
#
503
sub MakeSymLink
504
{
505
    my $no_clean;
506
    my $no_dot;
507
    my @args;
508
 
509
    #
510
    #   Extract options
511
    #
512
    foreach ( @_ )
513
    {
514
        if ( m/^--NoClean/i ) {
515
            $no_clean = 1;
516
 
517
        } elsif ( m/^--NoDotDot/i ) {
518
            $no_dot = 1;
519
 
520
        } elsif ( m/^--/ ) {
521
            Error ("MakeSymLink: Unknown option: $_");
522
 
523
        } else {
524
            push @args, $_;
525
        }
526
    }
527
 
528
    my ($old_file, $new_file) = @args;
529
 
530
    my $tfile = $DebianWorkDir . '/' . $new_file;
531
    $tfile =~ s~//~/~;
532
    Verbose ("Symlink $old_file -> $new_file" );
533
 
534
    #
535
    #   Create the directory in which the link will be placed
536
    #   Remove any existing file of the same name
537
    #
538
    my $dir = StripFileExt( $tfile );
539
    mkpath( $dir) unless -d $dir;
540
    unlink $tfile;
541
 
542
    #
543
    #   Determine a good name of the link
544
    #   Convert to a relative link in an attempt to prune them
545
    #
546
    my $sfile = $old_file;
547
    unless ( $no_clean )
548
    {
549
        $sfile = CalcRelPath( StripFileExt( $new_file ), $old_file );
550
        $sfile = $old_file if ( $no_dot && $sfile =~ m~^../~ );
551
    }
552
 
553
    my $result = symlink $sfile, $tfile;
554
    Error ("Cannot create symlink. $old_file -> $new_file") unless ( $result );
555
}
556
 
557
#-------------------------------------------------------------------------------
558
# Function        : CopyFile
559
#
560
# Description     : Copy a file to a target dir
561
#                   Used for text files, or files with fixed names
562
#
563
# Inputs          : $src
564
#                   $dst_dir    - Within the output workspace
565
#                   $dst_name   - Output Name [Optional]
566
#                   Options     - Common Copy Options
567
#
568
# Returns         : Full path to destination file
569
#
570
sub CopyFile
571
{
572
    CopyFileCommon( \&ResolveFile, @_ );
573
}
574
 
575
#-------------------------------------------------------------------------------
576
# Function        : CopyBinFile
577
#
578
# Description     : Copy a file to a target dir
579
#                   Used for executable programs. Will look in places where
580
#                   programs are stored.
581
#
582
# Inputs          : $src
583
#                   $dst_dir    - Within the output workspace
584
#                   $dst_name   - Output Name [Optional]
585
#
586
#                   Options:
587
#                       --FromPackage
588
#                       --SoftLink=xxxx
589
#                       --LinkFile=xxxx
590
#
591
#
592
# Returns         : Full path to destination file
593
#
594
sub CopyBinFile
595
{
596
    CopyFileCommon( \&ResolveBinFile, @_ );
597
}
598
 
599
#-------------------------------------------------------------------------------
600
# Function        : CopyLibFile
601
#
602
# Description     : Copy a file to a target dir
603
#                   Used for shared programs. Will look in places where
604
#                   shared libraries are stored.
605
#
606
# Inputs          : $src        - Base for 'realname' (no lib, no extension)
607
#                   $dst_dir    - Within the output workspace
608
#                   $dst_name   - Output Name [Optional, but not suggested]
609
#
610
# Returns         : Full path to destination file
611
#
612
# Notes           : Copying 'lib' files
613
#                   These are 'shared libaries. There is no provision for copying
614
#                   static libraries.
615
#
616
#                   The tool will attempt to copy a well-formed 'realname' library
617
#                   The soname of the library should be constructed on the target
618
#                   platform using ldconfig.
619
#                   There is no provision to copy the 'linker' name
620
#
621
#                   Given a request to copy a library called 'fred', then the
622
#                   well formed 'realname' will be:
623
#                           libfred[P|D|]].so.nnnnn
624
#                   where:
625
#                           nnnn is the library version
626
#                           [P|D|] indicates Production, Debug or None
627
#
628
#                   The 'soname' is held within the realname form of the library
629
#                   and will be created by lsconfig.
630
#
631
#                   The 'linkername' would be libfred[P|D|].so. This is only
632
#                   needed when linking against the library.
633
#
634
#
635
#                   The routine will also recognize Windows DLLs
636
#                   These are of the form fred[P|D|].nnnnn.dll
637
#
638
sub CopyLibFile
639
{
640
    CopyFileCommon( \&ResolveLibFile, @_ );
641
}
642
 
643
#-------------------------------------------------------------------------------
644
# Function        : CopyFileCommon
645
#
646
# Description     : Common ( internal File Copy )
647
#
648
# Inputs          : $resolver           - Ref to function to resolve source file
649
#                   $src                - Source File Name
650
#                   $dst_dir            - Target Dir
651
#                   $dst_name           - Target Name (optional)
652
#                   Options
653
#                   Options:
654
#                       --FromPackage
655
#                       --SoftLink=xxxx
656
#                       --LinkFile=xxxx
657
#
658
# Returns         : 
659
#
660
sub CopyFileCommon
661
{
662
    my $from_package = 0;
663
    my $isa_linkfile = 0;
664
    my @llist;
665
    my @args;
666
 
667
    #
668
    #   Parse options
669
    #
670
    foreach ( @_ )
671
    {
672
        if ( m/^--FromPackage/ ) {
673
            $from_package = 1;
674
 
675
        } elsif ( m/^--LinkFile/ ) {
676
            $isa_linkfile = 1;
677
 
678
        } elsif ( m/^--SoftLink=(.+)/ ) {
679
            push @llist, $1;
680
 
681
        } elsif ( m/^--/ ) {
682
            Error ("FileCopy: Unknown option: $_");
683
 
684
        } else {
685
            push @args, $_;
686
        }
687
    }
688
 
689
    #
690
    #   Extract non-options.
691
    #   These are the bits that are left over
692
    #
693
    my ($resolver, $src, $dst_dir, $dst_name ) = @args;
694
 
695
    #
696
    #   Clean up dest_dir. Must start with a / and not end with one
697
    #
698
    $dst_dir = "/$dst_dir/";
699
    $dst_dir =~ s~/+~/~g;
700
    $dst_dir =~ s~/$~~;
701
 
702
    Verbose ("CopyFile: $src, $dst_dir, " . ($dst_name || ''));
703
    foreach $src ( &$resolver( $from_package, $src ) )
704
    {
705
        my $dst_fname = $dst_name ? $dst_name : StripDir($src);
706
        my $dst_file = "$dst_dir/$dst_fname";
707
        Verbose ("CopyFile: Copy $src, $dst_file" );
708
 
709
 
710
        #
711
        #   LinkFiles are special
712
        #   They get concatenated to any existing LINKS File
713
        #
714
        if ( $isa_linkfile )
715
        {
716
            CatFile ( $src, "$dst_dir/.LINKS" );
717
        }
718
        else
719
        {
720
            mkpath( "$DebianWorkDir$dst_dir", 0, 0775);
721
            unlink ("$DebianWorkDir$dst_file");
722
            System ('cp','-f', $src, "$DebianWorkDir$dst_file" );
723
 
724
            foreach my $lname ( @llist )
725
            {
726
                $lname = $dst_dir . '/' . $lname unless ( $lname =~ m ~^/~ );
727
                MakeSymLink( $dst_file ,$lname);
728
            }
729
        }
730
    }
731
}
732
 
733
#-------------------------------------------------------------------------------
734
# Function        : CopyDir
735
#
736
# Description     : Copy a directory to a target dir
737
#
738
# Inputs          : $src_dir    - Local to the user
739
#                                 Symbolic Name
740
#                   $dst_dir    - Within the output workspace
741
#                   Options
423 dpurdie 742
#                       --Merge             - Don't delete first
743
#                       --Source=Name       - Source via Symbolic Name
425 dpurdie 744
#                       --FromPackage       - Souve via package roots
407 dpurdie 745
#
746
# Returns         :
747
#
748
sub CopyDir
749
{
750
    my ($src_dir, $dst_dir, @opts) = @_;
751
    my $opt_merge;
752
    my $opt_base;
411 dpurdie 753
    my $from_interface = 0;
407 dpurdie 754
 
755
    $dst_dir = $DebianWorkDir . '/' . $dst_dir;
756
    $dst_dir =~ s~//~/~;
757
 
758
    #
759
    #   Detect and expand Symbolic names in the Source Directory
760
    #
761
    foreach  ( @opts )
762
    {
763
        if ( m/^--Merge/ ) {
764
            $opt_merge = 1;
765
        } elsif ( m/^--Source=(.+)/ ) {
425 dpurdie 766
            my $name = $1;
767
            Verbose2 ("CopyDir: Source: $name");
768
            Error ("Source directory can only be specified once")
769
                if ( defined $opt_base );
770
 
771
            $name = lc($name);
407 dpurdie 772
            my %CopyDirSymbolic = (
773
                'interfaceincdir'   => $opt_interfaceincdir,
774
                'interfacelibdir'   => $opt_interfacelibdir,
775
                'interfacebindir'   => $opt_interfacebindir,
776
                'libdir'            => $opt_libdir,
777
                'bindir'            => $opt_bindir,
778
                'localincdir'       => $opt_localincdir,
779
                'locallibdir'       => $opt_locallibdir,
780
                'localbindir'       => $opt_localbindir,
781
                'packagebindir'     => $opt_pkgbindir,
782
                'packagelibdir'     => $opt_pkglibdir,
783
                'packagepkgdir'     => $opt_pkgpkgdir,
784
                'packagedir'        => $opt_pkgdir,
785
            );
786
 
787
            if ( exists $CopyDirSymbolic{$name} )
788
            {
789
                $opt_base = $CopyDirSymbolic{$name};
411 dpurdie 790
 
791
                #
792
                #   If sourceing from interface, then follow
793
                #   symlinks in the copy. All files will be links anyway
794
                #
795
                $from_interface = 1
796
                    if ( $name =~ m~^interface~ );
407 dpurdie 797
            }
798
            else
799
            {
800
                DebugDumpData ("CopyDirSymbolic", \%CopyDirSymbolic);
801
                Error ("CopyDir: Unknown Source Name: $name" );
802
            }
425 dpurdie 803
 
804
        } elsif ( m/^--FromPackage/ ) {
805
            Verbose2 ("CopyDir: FromPackage: $src_dir");
806
            Error ("Source directory can only be specified once")
807
                if ( defined $opt_base );
808
 
809
            my @path;
810
            foreach my $entry ( getPackageList() )
811
            {
812
                my $base = $entry->getBase(3);
813
                next unless ( defined $base );
814
                if ( -d $base . '/' . $src_dir )
815
                {
816
                    push @path, $base;
817
                }
818
            }
819
 
820
            Error ("CopyDir: Cannot find source dir in any package: $src_dir")
821
                if ( $#path < 0 );
822
            Error ("CopyDir: Requested path found in mutiple packages: $src_dir",
823
                    @path ) if ( $#path > 0 );
824
            $opt_base = pop @path;
825
 
826
            #
827
            #   If sourceing from interface, then follow symlinks in the copy.
828
            #   All files will be links anyway
829
            #
830
            #   This is a very ugly test for 'interface'
831
            #
832
            $from_interface = 1
833
                if ( $opt_base =~ m~/interface/~ );
834
 
407 dpurdie 835
        } else {
836
            Error ("CopyDir: Unknown option: $_" );
837
        }
838
    }
839
 
840
    $src_dir = $opt_base . '/' . $src_dir if ( $opt_base );
841
    $src_dir =~ s~//~/~g;
842
    $src_dir =~ s~/$~~;
843
 
844
    Verbose ("CopyDir: $src_dir, $dst_dir");
845
    Error ("CopyDir: Directory not found: $src_dir") unless ( -d $src_dir );
846
 
847
    #
423 dpurdie 848
    #   Setup the copy options
407 dpurdie 849
    #
423 dpurdie 850
    my %copyOpts;
851
    $copyOpts{'IgnoreDirs'} = ['.svn'];
852
    $copyOpts{'EmptyDirs'} = 1;
853
    $copyOpts{'DeleteFirst'} = 1 unless $opt_merge;
854
    $copyOpts{'Log'} = 1 if ( $opt_verbose > 1 );
855
    $copyOpts{'DuplicateLinks'} = 1 unless ( $from_interface );
407 dpurdie 856
 
857
    #
423 dpurdie 858
    #   Transfer the directory
407 dpurdie 859
    #
423 dpurdie 860
    JatsCopy::CopyDir ( $src_dir, $dst_dir, \%copyOpts );
407 dpurdie 861
 
862
    #
863
    #   Expand link files that may have been copied in
864
    #
865
    Verbose ("Locate LINKFILES in $DebianWorkDir");
866
    ExpandLinkFiles();
867
}
868
 
869
#-------------------------------------------------------------------------------
870
# Function        : AddInitScript
871
#
872
# Description     : Add an Init Script to the target
873
#                   Optionally create start and stop links
874
#
875
# Inputs          : $script     - Name of the init script
876
#                   $start      - Start Number
877
#                   $stop       - Stop Number
878
#                   Options:
879
#                       --NoCopy        - Don't copy the script, just add links
880
#                       --Afc           - Place in AFC init area
881
#                       --FromPackage   - Source is in a package
882
#
883
# Returns         : 
884
#
885
sub AddInitScript
886
{
887
    my $no_copy;
888
    my $basedir = "";
889
    my @args;
890
    my $from_package = 0;
891
 
892
    #
893
    #   Process and Remove options
894
    #
895
    foreach  ( @_ )
896
    {
897
        if ( m/^--NoCopy/ ) {
898
            $no_copy = 1;
899
 
900
        } elsif ( m/^--Afc/ ) {
901
            $basedir = "/afc";
902
 
903
        } elsif ( m/^--FromPackage/ ) {
904
            $from_package = 1;
905
 
906
        } elsif ( m/^--/ ) {
907
            Error ("AddInitScript: Unknown option: $_");
908
 
909
        } else {
910
            push @args, $_;
911
 
912
        }
913
    }
914
 
915
    my( $script, $start, $stop ) = @args;
916
    Error ("No script file specified") unless ( $script );
917
    Warning("AddInitScript: No start or stop index specified") unless ( $start || $stop );
918
    Verbose ("AddInitScript: $script, " . ($start || 'No Start') . ", " . ($stop || 'No Stop'));
919
    $script = ResolveFile($from_package, $script );
920
 
921
    my $tdir = $basedir . "/etc/init.d/init.d";
922
    my $base = StripDir($script);
923
 
924
    CopyFile( $script, $tdir ) unless $no_copy;
925
 
926
    my $link;
927
    if ( $start )
928
    {
929
        $link = sprintf ("${basedir}/etc/init.d/S%2.2d%s", $start, $base );
930
        MakeSymLink( "$tdir/$base", $link);
931
    }
932
 
933
    if ( $stop )
934
    {
935
        $link = sprintf ("${basedir}/etc/init.d/K%2.2d%s", $stop, $base );
936
        MakeSymLink( "$tdir/$base", $link);
937
    }
938
}
939
 
940
#-------------------------------------------------------------------------------
941
# Function        : CatFile
942
#
943
# Description     : Copy a file to the end of a file
944
#
945
# Inputs          : $src
946
#                   $dst    - Within the output workspace
947
#
948
# Returns         :
949
#
950
sub CatFile
951
{
952
    my ($src, $dst) = @_;
953
 
954
    $dst = $DebianWorkDir . '/' . $dst;
955
    $dst =~ s~//~/~;
956
    Verbose ("CatFile: $src, $dst");
957
    $src = ResolveFile(0, $src );
958
 
959
    open (SF, '<', $src)  || Error ("CatFile: Cannot open $src");
960
    open (DF, '>>', $dst) || Error ("CatFile: Cannot create:$dst");
961
    while ( <SF> )
962
    {
963
        print DF $_;
964
    }
965
    close (SF);
966
    close (DF);
967
}
968
 
969
#-------------------------------------------------------------------------------
970
# Function        : EchoFile
971
#
972
# Description     : Echo simple text to a file
973
#
974
# Inputs          : $file   - Within the output workspace
975
#                   $text
976
#
977
# Returns         : 
978
#
979
sub EchoFile
980
{
981
    my ($file, $text) = @_;
982
    Verbose ("EchoFile: $file");
983
 
984
    $file = $DebianWorkDir . '/' . $file;
985
    $file =~ s~//~/~;
986
 
987
    unlink $file;
988
    open (DT, ">", $file ) || Error ("Cannot create $file");
989
    print DT  $text || Error ("Cannot print to $file");
990
    close DT;
991
}
992
 
993
#-------------------------------------------------------------------------------
994
# Function        : SetFilePerms
995
#
996
# Description     : Set file permissions on one or more files or directories
997
#
998
# Inputs          : $perm           - Perm Mask
999
#                   @paths          - List of paths/files to process
1000
#                   Options
1001
#                       --Recurse   - Recurse subdirs
1002
#
1003
# Returns         : 
1004
#
1005
sub SetFilePerms
1006
{
1007
 
1008
    my @args;
1009
    my $perms;
1010
    my $recurse = 0;
1011
 
1012
    #
1013
    #   Process and Remove options
1014
    #
1015
    foreach  ( @_ )
1016
    {
1017
        if ( m/^--Recurse/ ) {
1018
            $recurse = 1;
1019
 
1020
        } elsif ( m/^--/ ) {
1021
            Error ("SetFilePerms: Unknown option: $_");
1022
 
1023
        } else {
1024
            push @args, $_;
1025
 
1026
        }
1027
    }
1028
 
1029
    $perms = shift @args;
1030
    Error ("SetFilePerms: No Permissions" ) unless ( $perms );
1031
 
1032
    foreach my $path ( @args )
1033
    {
1034
        Verbose ("Set permissions; $perms, $path");
1035
        my $full_path = $DebianWorkDir . '/' . $path;
1036
        if ( -f $full_path )
1037
        {
1038
            System ('chmod', $perms, $full_path );
1039
        }
1040
        elsif ( -d $full_path )
1041
        {
1042
            System ('chmod', '-R', $perms, $full_path ) if ($recurse);
1043
            System ('chmod', $perms, $full_path ) unless ($recurse);
1044
        }
1045
        else
1046
        {
1047
            Warning("SetFilePerms: Path not found: $path");
1048
        }
1049
    }
1050
}
1051
 
1052
#-------------------------------------------------------------------------------
1053
# Function        : CreateDir
1054
#
1055
# Description     : Create a directory within the target workspace
1056
#
1057
# Inputs          : $path           - Name of the target directory
1058
#
1059
# Returns         : Nothing
1060
#
1061
sub CreateDir
1062
{
1063
    my ($path) = @_;
1064
 
1065
    Verbose ("Create Dir: $path");
1066
    mkpath( $DebianWorkDir . '/' . $path );
1067
}
1068
 
1069
#-------------------------------------------------------------------------------
1070
# Function        : IsProduct
1071
#                   IsPlatform
1072
#                   IsTarget
1073
#
1074
# Description     : This function allows some level of control in the
1075
#                   packaging scripts. It will return true if the current
1076
#                   product is listed.
1077
#
1078
#                   Ugly after thought
1079
#
1080
#                   Intended use:
1081
#                       Xxxxxx(...) if (IsProduct( 'aaa',bbb' );
1082
#
1083
# Inputs          : products    - a list of products to compare against
1084
#
1085
# Returns         : True if the current build is for one of the listed products
1086
#
1087
sub IsProduct
1088
{
1089
    foreach ( @_ )
1090
    {
1091
        return 1 if ( $opt_product eq $_ );
1092
    }
1093
    return 0;
1094
}
1095
 
1096
sub IsPlatform
1097
{
1098
    foreach ( @_ )
1099
    {
1100
        return 1 if ( $opt_platform eq $_ );
1101
    }
1102
    return 0;
1103
}
1104
 
1105
sub IsTarget
1106
{
1107
    foreach ( @_ )
1108
    {
1109
        return 1 if ( $opt_target eq $_ );
1110
    }
1111
    return 0;
1112
}
1113
 
1114
 
1115
#-------------------------------------------------------------------------------
1116
# Function        : FindFiles
1117
#
1118
# Description     : Locate files within a given dir tree
1119
#
1120
# Inputs          : $root           - Base of the search
1121
#                   $match          - Re to match
1122
#
1123
# Returns         : A list of files that match
1124
#
1125
my @FIND_LIST;
1126
my $FIND_NAME;
1127
 
1128
sub FindFiles
1129
{
1130
    my ($root, $match ) = @_;
1131
    Verbose2("FindFiles: Root: $root, Match: $match");
1132
 
1133
    #
1134
    #   Becareful of closure, Must use globals
1135
    #
1136
    @FIND_LIST = ();
1137
    $FIND_NAME = $match;
1138
    File::Find::find( \&find_files, $root);
1139
 
1140
    #
1141
    #   Find callback program
1142
    #
1143
    sub find_files
1144
    {
1145
        my $item =  $File::Find::name;
1146
 
1147
        return if ( -d $File::Find::name );
1148
        return unless ( $_ =~ m~$FIND_NAME~ );
1149
        push @FIND_LIST, $item;
1150
    }
1151
    return @FIND_LIST;
1152
}
1153
 
1154
#-------------------------------------------------------------------------------
1155
# Function        : CalcRelPath
1156
#
1157
# Description     : Return the relative path to the current working directory
1158
#                   as provided in $Cwd
1159
#
1160
# Inputs          : $Cwd - Base dir
1161
#                   $base - Path to convert
1162
#
1163
# Returns         : Relative path from the $Cwd
1164
#
1165
sub CalcRelPath
1166
{
1167
    my ($Cwd, $base) = @_;
1168
 
1169
    my @base = split ('/', $base );
1170
    my @here = split ('/', $Cwd );
1171
    my $result;
1172
 
1173
    Debug("RelPath: Source: $base");
1174
 
1175
    return $base unless ( $base =~ m~^/~ );
1176
 
1177
    #
1178
    #   Remove common bits from the head of both lists
1179
    #
1180
    while ( $#base >= 0 && $#here >= 0 && $base[0] eq $here[0] )
1181
    {
1182
        shift @base;
1183
        shift @here;
1184
    }
1185
 
1186
    #
1187
    #   Need to go up some directories from here and then down into base
1188
    #
1189
    $result = '../' x ($#here + 1);
1190
    $result .= join ( '/', @base);
1191
    $result = '.' unless ( $result );
1192
    $result =~ s~//~/~g;
1193
    $result =~ s~/$~~;
1194
 
1195
    Debug("RelPath: Result: $result");
1196
    return $result;
1197
}
1198
 
1199
#-------------------------------------------------------------------------------
1200
# Function        : ExpandLinkFiles
1201
#
1202
# Description     : Look for .LINK files in the output image and expand
1203
#                   the links into softlinks
1204
#
1205
# Inputs          : None
1206
#                   The rouine works on the $DebianWorkDir directory tree
1207
#
1208
# Returns         : Nothing
1209
#                   Will remove .LINKS files that are processed
1210
#
1211
sub ExpandLinkFiles
1212
{
1213
    foreach my $linkfile ( FindFiles( $DebianWorkDir, ".LINKS" ))
1214
    {
1215
        next if ( $linkfile =~ m~/\.svn/~ );
1216
        my $BASEDIR = StripFileExt( $linkfile );
1217
        $BASEDIR =~ s~^$DebianWorkDir/~~;
1218
        Verbose "Expand links: $BASEDIR";
1219
 
1220
        open (LF, "<", $linkfile ) || Error ("Cannot open link file: $linkfile" );
1221
        while ( <LF> )
1222
        {
1223
            chomp;
1224
            next if ( m~^#~ );
1225
            next unless ( $_ );
1226
            my ($link, $file) = split;
1227
 
1228
            MakeSymLink($file ,"$BASEDIR/$link", '--NoDotDot' );
1229
        }
1230
        close (LF);
1231
        unlink $linkfile;
1232
    }
1233
}
1234
 
1235
#-------------------------------------------------------------------------------
1236
# Function        : ResolveFile
1237
#
1238
# Description     : Determine where the source for a file is
415 dpurdie 1239
#                   Will look in (default):
407 dpurdie 1240
#                       Local directory
1241
#                       Local Include
415 dpurdie 1242
#                   Or  (FromPackage)
1243
#                       Our Package directory
1244
#                       Interface directory (BuildPkgArchives)
1245
#                       Packages (LinkPkgArchive)
1246
#
407 dpurdie 1247
#                   Will scan 'parts' subdirs
1248
#
1249
# Inputs          : $from_package       - 0 - Local File
1250
#                   $file
1251
#
1252
# Returns         : Path
1253
#
1254
sub ResolveFile
1255
{
1256
    my ($from_package, $file) = @_;
1257
    my $wildcard = ($file =~ /[*?]/);
415 dpurdie 1258
    my @path;
407 dpurdie 1259
 
1260
    #
415 dpurdie 1261
    #   Determine the paths to search
1262
    #
1263
    if ( $from_package )
1264
    {
1265
        unless ( @ResolveFileList )
1266
        {
1267
            push @ResolveFileList, $opt_pkgdir;
1268
            foreach my $entry ( getPackageList() )
1269
            {
1270
                push @ResolveFileList, $entry->getBase(3);
1271
            }
1272
        }
1273
        @path = @ResolveFileList;
1274
    }
1275
    else
1276
    {
1277
        @path = ('.', $opt_localincdir);
1278
    }
1279
 
1280
    #
407 dpurdie 1281
    #   Determine a full list of 'parts' to search
1282
    #   This is provided within the build information
1283
    #
1284
    my @parts = getPlatformParts ();
1285
    push @parts, '';
1286
 
1287
    my @done;
1288
    foreach my $root (  @path )
1289
    {
1290
        foreach my $subdir ( @parts )
1291
        {
1292
            my $sfile;
415 dpurdie 1293
            $sfile = "$root/$subdir/$file";
1294
            $sfile =~ s~//~/~g;
1295
            $sfile =~ s~^./~~g;
1296
            Verbose2("LocateFile: $sfile, $root, $subdir");
1297
            if ( $wildcard )
1298
            {
1299
                push @done, glob ( $sfile );
1300
            }
1301
            else
1302
            {
1303
                push @done, $sfile if ( -f $sfile || -l $sfile )
1304
            }
407 dpurdie 1305
        }
1306
    }
1307
 
415 dpurdie 1308
    Error ("ResolveFile: File not found: $file", "Search Path:", @path)
407 dpurdie 1309
        unless ( @done );
1310
 
1311
    Warning ("ResolveFile: Multiple instances of file found. Only first is used", @done)
1312
        if ( $#done > 0 && ! $wildcard && !wantarray );
1313
 
1314
    return wantarray ? @done : $done[0];
1315
}
1316
 
1317
#-------------------------------------------------------------------------------
1318
# Function        : ResolveBinFile
1319
#
415 dpurdie 1320
# Description     : Determine where the source for a BIN file is
1321
#                   Will look in (default):
1322
#                       Local directory
1323
#                       Local Include
1324
#                   Or  (FromPackage)
1325
#                       Our Package directory
1326
#                       Interface directory (BuildPkgArchives)
1327
#                       Packages (LinkPkgArchive)
407 dpurdie 1328
#                   Will scan 'parts' subdirs
1329
#
1330
# Inputs          : $from_package       - 0 - Local File
415 dpurdie 1331
#                   $file
407 dpurdie 1332
#
1333
# Returns         : Path
1334
#
1335
sub ResolveBinFile
1336
{
1337
    my ($from_package, $file) = @_;
1338
    my @path;
1339
    my @types;
1340
    my $wildcard = ($file =~ /[*?]/);
1341
 
415 dpurdie 1342
    #
1343
    #   Determine the paths to search
1344
    #
407 dpurdie 1345
    if ( $from_package )
1346
    {
415 dpurdie 1347
        unless ( @ResolveBinFileList )
1348
        {
1349
            push @ResolveBinFileList, $opt_pkgdir . '/bin';
1350
            foreach my $entry ( getPackageList() )
1351
            {
1352
                if ( my $path = $entry->getBase(3) )
1353
                {
1354
                    $path .= '/bin';
1355
                    push @ResolveBinFileList, $path if ( -d $path );
1356
                }
1357
            }
1358
        }
1359
        @path = @ResolveBinFileList;
407 dpurdie 1360
        @types = ($opt_type, '');
1361
    }
1362
    else
1363
    {
1364
        @path = ($opt_bindir, $opt_localbindir);
1365
        @types = '';
1366
    }
1367
 
1368
    #
1369
    #   Determine a full list of 'parts' to search
1370
    #   This is provided within the build information
1371
    #
1372
    my @parts = getPlatformParts ();
1373
    push @parts, '';
1374
 
1375
    my @done;
1376
    foreach my $root (  @path )
1377
    {
1378
        foreach my $subdir ( @parts )
1379
        {
1380
            foreach my $type ( @types )
1381
            {
1382
                my $sfile;
1383
                $sfile = "$root/$subdir$type/$file";
1384
                $sfile =~ s~//~/~g;
1385
                Verbose2("LocateBinFile: $sfile");
1386
                if ( $wildcard )
1387
                {
1388
                    push @done, glob ( $sfile );
1389
                }
1390
                else
1391
                {
415 dpurdie 1392
                    push @done, $sfile if ( -f $sfile || -l $sfile )
407 dpurdie 1393
                }
1394
            }
1395
        }
1396
    }
1397
 
415 dpurdie 1398
    Error ("ResolveBinFile: File not found: $file", "Search Path:", @path)
407 dpurdie 1399
        unless ( @done );
1400
 
1401
    Warning ("ResolveBinFile: Multiple instances of file found. Only first is used", @done)
1402
        if ( $#done > 0 && ! $wildcard && !wantarray );
1403
    return wantarray ? @done : $done[0];
1404
}
1405
 
1406
#-------------------------------------------------------------------------------
1407
# Function        : ResolveLibFile
1408
#
415 dpurdie 1409
# Description     : Determine where the source for a LIB file is
1410
#                   Will look in (default):
1411
#                       Local directory
1412
#                       Local Include
1413
#                   Or  (FromPackage)
1414
#                       Our Package directory
1415
#                       Interface directory (BuildPkgArchives)
1416
#                       Packages (LinkPkgArchive)
407 dpurdie 1417
#                   Will scan 'parts' subdirs
1418
#
1419
# Inputs          : $from_package       - 0 - Local File
415 dpurdie 1420
#                   $file       - Basename for a 'realname'
407 dpurdie 1421
#                                 Do not provide 'lib' or '.so' or version info
1422
#                                 May contain embedded options
1423
#                                   --Dll - use Windows style versioned DLL
1424
#                                   --VersionDll - USe the versioned DLL
1425
#
1426
# Returns         : Path
1427
#
1428
sub ResolveLibFile
1429
{
1430
    my ($from_package, $file) = @_;
1431
    my $wildcard = ($file =~ /[*?]/);
1432
    my @options;
1433
    my $num_dll;
415 dpurdie 1434
    my @path;
407 dpurdie 1435
    #
1436
    #   Extract options from file
1437
    #
409 alewis 1438
    $num_dll = 0;
407 dpurdie 1439
    ($file, @options) = split ( ',', $file);
1440
    foreach ( @options )
1441
    {
1442
        if ( m/^--Dll/ ) {
1443
            $num_dll = 1;
1444
        } elsif ( m/^--VersionDll/ ) {
1445
            $num_dll = 2;
1446
        } else {
1447
            Error ("Unknown suboption to ResolveLibFile: $_" );
1448
        }
1449
    }
1450
 
1451
    #
415 dpurdie 1452
    #   Determine the paths to search
1453
    #
1454
    if ( $from_package )
1455
    {
1456
        unless ( @ResolveLibFileList )
1457
        {
1458
            push @ResolveLibFileList, $opt_pkgdir . '/lib';
1459
            foreach my $entry ( getPackageList() )
1460
            {
1461
                push @ResolveLibFileList, $entry->getLibDirs(3);
1462
            }
1463
        }
1464
        @path = @ResolveLibFileList;
1465
    }
1466
    else
1467
    {
1468
        @path = ($opt_libdir, $opt_locallibdir);
1469
    }
1470
 
1471
    #
407 dpurdie 1472
    #   Determine a full list of 'parts' to search
1473
    #   This is provided within the build information
1474
    #
1475
    my @parts = getPlatformParts ();
1476
    push @parts, '';
1477
 
1478
    my @done;
1479
    foreach my $root (  @path )
1480
    {
1481
        foreach my $type ( $opt_type, '' )
1482
        {
1483
            foreach my $subdir ( @parts )
1484
            {
1485
                my $sfile;
1486
                my $exact;
1487
                if ( $num_dll == 2 ) {
1488
                    $sfile = $file . $type . '.*.dll' ;
1489
                } elsif ( $num_dll == 1 ) {
1490
                    $sfile = $file . $type . '.dll' ;
1491
                    $exact = 1;
1492
                } else {
1493
                    $sfile = "lib" . $file . $type . '.so.*';
1494
                }
1495
 
1496
                $sfile = "$root/$subdir/$sfile";
1497
                $sfile =~ s~//~/~g;
1498
                Verbose2("LocateLibFile: $sfile");
1499
                if ( $exact )
1500
                {
415 dpurdie 1501
                    push @done, $sfile if ( -f $sfile || -l $sfile );
407 dpurdie 1502
                }
419 dpurdie 1503
                elsif ($num_dll)
407 dpurdie 1504
                {
1505
                    push @done, glob ( $sfile );
1506
                }
419 dpurdie 1507
                else
1508
                {
1509
                    #
1510
                    #   Looking for .so files
1511
                    #   Filter out the soname so files
1512
                    #   Assume that the soname is shorter than the realname
1513
                    #
1514
                    my %sieve;
1515
                    foreach ( glob ( $sfile )  )
1516
                    {
421 alewis 1517
                        m~(.*\.so\.)([\d\.]*\d)$~;
1518
                        if ( $1 )
1519
                        {
1520
                            my $file = $1;
1521
                            my $len = exists $sieve{$file} ? length($sieve{$file}) : 0;
1522
                            $sieve{$file} = $_
1523
                                if ( $len == 0 || length($_) > $len );
1524
                        }                                
419 dpurdie 1525
                    }
1526
 
1527
                    push @done, values %sieve;
1528
                }
407 dpurdie 1529
            }
1530
        }
1531
    }
1532
 
415 dpurdie 1533
    Error ("ResolveLibFile: File not found: $file", "Search Path:", @path)
407 dpurdie 1534
        unless ( @done );
1535
 
1536
    Warning ("ResolveLibFile: Multiple instances of file found. Only first is used", @done)
1537
        if ( $#done > 0 && ! $wildcard && !wantarray );
1538
 
1539
    return wantarray ? @done : $done[0];
1540
}
1541
 
1542
 
1543
#-------------------------------------------------------------------------------
1544
# Function        : AUTOLOAD
1545
#
1546
# Description     : Intercept bad user directives and issue a nice error message
1547
#                   This is a simple routine to report unknown user directives
1548
#                   It does not attempt to distinguish between user errors and
1549
#                   programming errors. It assumes that the program has been
1550
#                   tested. The function simply report filename and line number
1551
#                   of the bad directive.
1552
#
1553
# Inputs          : Original function arguments ( not used )
1554
#
1555
# Returns         : This function does not return
1556
#
1557
our $AUTOLOAD;
1558
sub AUTOLOAD
1559
{
1560
    my $fname = $AUTOLOAD;
1561
    $fname =~ s~^main::~~;
1562
    my ($package, $filename, $line) = caller;
1563
 
1564
    Error ("Directive not known or not allowed in this context: $fname",
1565
           "Directive: $fname( @_ );",
1566
           "File: $filename, Line: $line" );
1567
}
1568
 
1569
 
1570
1;
1571