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