Subversion Repositories DevTools

Rev

Rev 7300 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
4247 dpurdie 1
########################################################################
7300 dpurdie 2
# COPYRIGHT - VIX IP PTY LTD ("VIX"). ALL RIGHTS RESERVED.
227 dpurdie 3
#
4
# Module name   : installpkg.pl
5
# Module type   : Makefile system
4247 dpurdie 6
# Compiler(s)   : Perl
7
# Environment(s): jats
8
#
227 dpurdie 9
# Description:    Install package definition file.
4247 dpurdie 10
#                 This file is invoked by the BuildPkgArchive directive
227 dpurdie 11
#
12
###############################################################################
13
#
14
#   The main purpose of this program is to take packages from dpkg_archive and
15
#   place them into the build's 'interface' directory in a form that can be used
16
#   by the rest of the build. This process is complicated by the number of
17
#   variants in package format. In the pre-JATS2 days the users were encourgaed
4247 dpurdie 18
#   to dream up there own format for packages. The hard part of this script is
227 dpurdie 19
#   dealing with all the known variations. Under JATS2 the default package
20
#   layout is much easier to implemenet and users generally adhere to it.
21
#
22
#   The target 'interface' format is of the form:
23
#
24
#           interface/
25
#               include/
26
#                   PLATFORM/
27
#                   PRODUCT/
28
#                   TARGET/
29
#               lib/                                    - Should not be populated
30
#                   PLATFORM/                           - Ideal
31
#                   PRODUCT/                            - Not practical
32
#                   TARGET/
33
#               bin/                                    - Should not be populated
34
#                   PLATFORM[P|D]/                      - Ideal
35
#                   PRODUCT[P|D]/                       - Not practical
36
#                   TARGET[P|D]/
37
#
38
#               tools/
39
#                   bin/
40
#                       MACHTYPE/
41
#                   scrips/
42
#                       MACHTYPE/
43
#
44
#               pkg/
45
#
46
#               OTHERS
47
#
48
#
49
 
50
use strict;
51
use warnings;
52
 
53
use JatsError;
54
use DescPkg;
55
use JatsEnv;
56
 
57
use Cwd;
58
use File::Basename;
59
use File::Find;
60
use File::Path;
61
use File::Copy;
62
 
63
#
64
#   Global variables
65
#
66
our $GBE_VERBOSE;
67
our $GBE_MACHTYPE;
68
 
69
my %PLATFORMS = ();
70
my %dirs_processed = ();
71
my $symlinks;
331 dpurdie 72
my $allow_overwrite = 0;
227 dpurdie 73
 
74
#...
75
#
76
my $INTDIR;                                 # Interface directory (target)
77
my $BINDIR;                                 # Build directory (Not used)
78
my $PKG_ROOT=cwd();                         # Package source (CWD)
79
 
80
#
81
#   Global used for File::Find callback function
82
#
83
my $FF_SRC_DIR="";                          # Src subdir base
84
my $FF_DST_DIR="";                          # Dst subdir base
85
 
86
################################################################################
87
#
88
#
89
#
90
#   Init the error reporting package
91
#
92
ErrorConfig( 'name'    => 'installpkg' );
93
 
94
#
95
#   Ensure required environment variables are present
96
#
97
EnvImport ('GBE_MACHTYPE');
98
EnvImport ('GBE_VERBOSE');
99
 
100
ErrorConfig( 'verbose' => $GBE_VERBOSE );
101
 
102
#
103
#   Determine if symlinks are available
104
#   They may not be available at all, in which case we don't even try
105
#
106
$symlinks = eval { symlink("",""); 1 } || 0;
107
 
108
#
109
#   Report machine information
110
#
331 dpurdie 111
Verbose ("GBE_VERBOSE    : $GBE_VERBOSE" );
112
Verbose ("GBE_MACHTYPE   : $GBE_MACHTYPE" );
113
Verbose ("SymLinks       : $symlinks" );
114
Verbose ("AllowOverwrite : $allow_overwrite" );
115
Verbose ("Cmd            : @ARGV");
227 dpurdie 116
 
117
################################################################################
118
#
119
#   Parse user arguments
120
#   Arguments
121
#       Arg0    - Interface directory
122
#       Arg1    - Build Directory ( Not Used )
123
#       Arg2..  - A list of Platform specifications
124
#                 One for each platform that needs to be processed
125
#                 Each plaform specification consists of:
126
#                   --Platform:PlatformName:PlatformParts:Options
127
#                   Where:
128
#                       --Platform      - is a leadin switch
129
#                       PlatformName    - The the target platform
130
#                       PlatformParts   - A colon seperated list of platform 'parts'
131
#                                         This consist of: Platform, Product, ... Target
132
#
133
$INTDIR = shift @ARGV;
134
Error("Interface directory not specified") unless( defined $INTDIR );
135
Error("Interface directory not found: $INTDIR") unless( -d $INTDIR );
136
 
137
$BINDIR = shift @ARGV;
138
Error("Program directory not specified")   unless( defined $BINDIR );
139
Error("Program directory not found: $BINDIR") unless( -d $BINDIR );
140
 
141
foreach ( @ARGV )
142
{
143
    if ( /^--Platform/ ) {
144
        Verbose2 ("ARGV = <$_>");
145
        my ($tmpVar, @platforms) = split /:/, $_;
146
 
147
        my $platform = $platforms[0];
148
        $PLATFORMS{$platform}{'PARTS'} = \@platforms;
149
 
150
    } elsif ( /^--NoSymlinks/i ) {
151
        $symlinks = 0;
152
 
331 dpurdie 153
    } elsif ( /^--AllowOverWrite/i ) {
154
        $allow_overwrite = 1;
155
 
227 dpurdie 156
    } else {
157
        Warning("Unknown argument(ignored): $_");
158
 
159
    }
160
}
161
 
162
#
163
# lets review what we have read in
164
#
165
foreach my $i ( sort keys %PLATFORMS )
166
{
167
    Verbose( "PLATFORMS{$i} = ", join( ',', @{$PLATFORMS{$i}{'PARTS'}} ) );
168
}
169
 
170
################################################################################
171
#   Read in the Packages descpkg file
172
#   The contents are not used. More a sanity test than anything else
173
#
174
my $rec = ReadDescpkg ( "descpkg" );
175
if ( $rec )
176
{
177
    Verbose ("Installing the package $rec->{NAME} $rec->{VERSION} $rec->{PROJ}");
178
}
179
else
180
{
181
    Message ("Installing the package ($PKG_ROOT)");
182
}
183
 
184
 
185
################################################################################
186
#
187
#   Lets deal with the top level flat dirs include dir(s)
188
#
189
#   For each directory listed in the ModuleList simply duplicate the entire
190
#   directory to the target location
191
#
192
my (@ModuleList) = ( "etc",
193
                     "swsfiles", 
194
                     "classes", 
195
                     "jar",
196
                     "sar",
197
                     "sql", 
198
                     "war", 
199
                     "scripts", 
200
                     "infofiles", 
201
                     "jsp", 
202
                     "thx", 
203
                     "rox", 
204
                     "rpt", 
205
                     "java", 
206
                     "achtml", 
207
                     "epedia", 
208
                     "doc", 
209
                     "docs",
210
                     "devcd",
211
                     "dat",
212
                     "mug",
261 dpurdie 213
                     "wsdl",                # Store wsdls
227 dpurdie 214
                     "include",             # Need the entire directory
215
                     "MergeModules",        # InstallShield Merge Modules
216
                     "deployfiles",         # Deployment internals
7323 dpurdie 217
                     "mavenRepository",     # Formatted dependencies
227 dpurdie 218
);
219
 
220
foreach my $i (@ModuleList)
221
{
222
    do_dir( $i, $i);
223
}
224
 
225
################################################################################
226
#
227
#   Process a "pkg" directory
228
#
229
#   There are two forms of pkg directory
230
#       1) pkg directory contains ONLY directories of the form pkg.$(GBE_MACHTYPE)
231
#          These are processed by coying:
232
#               pkg/pkg.GBE_MACHTYPE -> pkg
233
#
234
#       2) pkg without any pkg.* subdirs
235
#          Copy the entire subtree
236
#
237
#       3) Mixture
238
#          Cannot handle
239
#
240
#
241
my (@ModuleList2) =  ( "pkg" );
242
 
243
foreach my $i (@ModuleList2)
244
{
245
    #
246
    #   Determine the mode of operation
247
    #   Scan files in the directory for known format
248
    #
249
    my @dir_list = glob( "$i/*" );
250
    my $pkg_count = 0;
251
    my $other_count = 0;
252
 
253
    foreach ( @dir_list )
254
    {
255
        if ( m~/$i\.~ )
256
        {
257
            $pkg_count++;
258
        }
259
        else
260
        {
261
            $other_count++;
262
        }
263
    }
264
 
265
    if ( $pkg_count && $other_count )
266
    {
267
        Warning( "Cannot handle mixed \"${i}\" directory",
268
                 "Only machine directory will be copied" );
269
    }
270
 
271
    if ( $pkg_count )
272
    {
273
        #
274
        #   pkg/pkg.GBE_MACHTYPE -> pkg
275
        #
276
        do_dir("$i/$i\.$GBE_MACHTYPE", $i, );
277
    }
278
    else
279
    {
280
        #
281
        #   pkg -> pkg
282
        #
283
        do_dir($i, $i);
284
    }
285
}
286
 
287
 
288
################################################################################
289
#
290
#   Deal with the complex directories:
291
#           bin,
292
#           lib,
293
#           inc
294
#           include
295
#
296
#   Look for, and process the first of:
297
#
298
#   for each item in module list we shall process (if it exists) 
299
#   the following variants:
300
#
301
#       module.<platform>
302
#       module.<product>
303
#       module.<target>
304
#
305
#       module/<platform>
306
#       module/<product>
307
#       module/<target>
308
#
309
#   The platform, product and target are all passed on the command
310
#   line.  They are configured in the build.pl using the BuildProduct
311
#   directives.
312
#
313
#   For the bin dirs we need to consider the 'Debug' and 'Prod' 
314
#   build types as well as some cots packages that are both.
315
#
316
#   For the bin and lib dirs we also need to consider the format:
317
#       bin/bin.<platform>
318
#       lib/lib.<platform>
319
#
320
#
321
 
322
my %ModuleList3 =   (
323
                    "lib"           => 1,       # Copy root files
324
                    "inc"           => 1,       # Copy root files
325
                    "bin"           => 0,       # Should not be any root files
326
                    "include"       => 0,       # Root files already processed
327
                    );
328
 
329
foreach my $i (sort keys %ModuleList3)
330
{
331
    my $mDstDir;
332
    my $bType;
333
    my $mPart;
334
    my $mode =  $ModuleList3{$i};
335
 
336
    Verbose ("Processing: [Mode:$mode] $i");
337
 
338
    foreach my $j ( sort keys %PLATFORMS )
339
    {
340
        foreach $bType ( 'D', 'P', '' )
341
        {
342
            foreach $mPart ( sort @{$PLATFORMS{$j}{'PARTS'}} )
343
            {
344
                $mDstDir = "$i/$mPart$bType";
345
 
346
                #
347
                #   Try various combinations of directories to catter for
348
                #   all the crazy legacy combinations
349
                #
350
                do_dir("$i.$mPart$bType"    ,$mDstDir);
351
                do_dir("$i/$mPart$bType"    ,$mDstDir);
352
                do_dir("$i/$i.$mPart$bType" ,$mDstDir);
353
            }
354
        }
355
    }
356
 
357
    #
358
    # Transfer files in the root directory if required
359
    #
360
    # Now lets us deal with the simple case
361
    # here we are only interested in the top level files
362
    # sub-dirs are handles separately.
363
    #
364
    if ( ($mode & 1) && -d $i)
365
    {
366
        Verbose ("Processing: $i - Copy root directory files");
367
        do_FilesOnly ( $i );
368
    }
369
}
370
 
371
################################################################################
372
#   Deal with toolset extensions
373
#   These are JATS extensions that are platform specific and not a function of
374
#   the target. ie: If we are building on a 'win32' piece of hardware then we
375
#   need the win32 tools, independant of the target platforms
376
#
377
#   Use GBE_MACHTYPE to determine correct subdirs
378
#
379
my %ModuleList4 =   (
380
                    "tools/bin"             => 3,       # Copy GBE_MACHTYPE + root files
381
                    "tools/scripts"         => 4,       # Copy Subdir
382
                    "gbe"                   => 4,       # JATS General Build Environment
383
                    );
384
foreach my $i (sort keys %ModuleList4)
385
{
386
    my $mode = $ModuleList4{$i};
387
    Verbose ("Processing: $i, Machine Type: $GBE_MACHTYPE, Mode: $mode");
388
 
389
    #
390
    #   Transfer a machine specfic subdir
391
    #
392
    if ( $mode & 1 )
393
    {
394
        do_dir("$i.$GBE_MACHTYPE", "$i/$GBE_MACHTYPE") ;
395
        do_dir("$i/$GBE_MACHTYPE", "$i/$GBE_MACHTYPE") ;
396
    }
397
 
398
    #
399
    # Transfer files in the root directory if required
400
    #
401
    # Now lets us deal with the simple case
402
    # here we are only interested in the top level files
403
    # sub-dirs are handles separately.
404
    #
405
    if ( ($mode & 2) && -d $i)
406
    {
407
        Verbose ("Processing: $i - Copy root directory files");
408
        do_FilesOnly ( $i );
409
    }
410
 
411
    #
412
    #   Copy the entire subtree
413
    #   Used for non-machine specifc directories
414
    #
415
    if ( ($mode & 4) && -d $i)
416
    {
417
        Verbose ("Processing: $i - Copy directory tree");
418
        do_dir($i, $i) ;
419
    }
420
 
421
}
422
 
423
 
424
 
425
# done
426
exit 0;
427
 
428
 
429
#------------------------------------------------------------------------------
430
#------------------------------------------------------------------------------
431
#------------------------------------------------------------------------------
432
# subroutines
433
#------------------------------------------------------------------------------
434
#------------------------------------------------------------------------------
435
#------------------------------------------------------------------------------
436
 
437
#-------------------------------------------------------------------------------
438
# Function        : do_FilesOnly
439
#
440
# Description     : Copy all files in the current directory to the target
441
#                   directory. Assume that the target directory will be called
442
#                   the same as the source directory
443
#
444
#                   Do not process sub directories. These may be handled elsewhere
445
#
446
# Inputs          : $dir        - Src and Dst subdir name
447
#
448
# Returns         : Nothing
449
#
450
sub do_FilesOnly
451
{
452
    my ($dir) = @_;
453
    Verbose2 ("do_FilesOnly: dir=[$dir]");
454
 
455
    # define the type of dir we are working on
456
 
457
    my ($srcDir) = "$PKG_ROOT/$dir";
458
    my ($dstDir) = "$INTDIR/$dir";
459
 
460
    Verbose2("do_FilesOnly: INTDIR=[$INTDIR]");
461
    Verbose2("do_FilesOnly: dstDir=[$dstDir]");
462
    Verbose2("do_FilesOnly: srcDir=[$srcDir]");
463
 
464
    #
465
    # Create the interface dir if it does not exists
466
    #
467
    mkpath ( $dstDir, $GBE_VERBOSE, 0775) unless ( -d $dstDir );
468
 
469
 
470
    # Have a valid dst value we now need to get a hold of all the
471
    # lib scripts files.
472
    #
473
    local *DIR;
474
    opendir ( DIR, $srcDir ) or  Error ("Failed to open dir [$srcDir]");
475
 
476
    #
477
    # Process all directory entries
478
    #
479
    while (defined(my $_item = readdir(DIR)))
480
    {
481
        next if ( $_item eq '.' );
482
        next if ( $_item eq '..' );
483
 
484
        my $srcFile = "$srcDir/$_item";
485
        if ( -d $srcFile )
486
        {
487
            Verbose2 ("NOT processing dir item [$srcFile]");
488
        }
489
        else
490
        {
491
            FileLinkCopy ($srcFile, "$dstDir/$_item" );
492
        }
493
    }
285 dpurdie 494
    closedir DIR;
227 dpurdie 495
 
496
 
497
    # done
498
    return 1;
499
}
500
#-------------------------------------------------------------------------------
501
# Function        : do_dir
502
#
503
# Description     : Transfer an entire subdirectory tree
504
#                   Can detect that the tree has already been processed
505
#
506
# Inputs          : $src            - Source subdir (within PKG_ROOT)
507
#                   $dst            - Target path (within INTDIR)
508
#
509
# Returns         : Nothing
510
#
511
sub do_dir
512
{
513
    my ($src, $dst) = @_;
514
    Verbose2 ("do_dir: src=[$src], dst=[$dst]");
515
 
516
    #
517
    #   Prevent processing of the same source directory by multiple
518
    #   operations. Need only do them once
519
    #
520
    if ( $dirs_processed{$src} )
521
    {
522
        Verbose2 ("do_dir: Already processed");
523
        return 1;
524
    }
525
 
526
    $dirs_processed{$src} = 1;
527
 
528
    #
529
    #   Only if it exists
530
    #   Do the test in this function to simplify processing
531
    #
532
    unless ( -d $src )
533
    {
534
        Verbose2 ("do_dir: Directory not found");
535
        return 0;
536
    }
537
 
538
    #
539
    #   Setup values for the File::Find callback
540
    #   These need to be global due to the way that File::Find works
541
    #
542
    $FF_SRC_DIR = "$PKG_ROOT/$src";
543
    $FF_DST_DIR = "$INTDIR/$dst";
544
 
545
    Verbose2("do_dir: FF_SRC_DIR=[$FF_SRC_DIR]");
546
    Verbose2("do_dir: FF_DST_DIR=[$FF_DST_DIR]");
547
 
548
    #
549
    #   Handle directories that are really symbolic links
550
    #   This will only occur on system that handle symlinks
551
    #   May not always want to use symlinks.
552
    #
553
    if ( $symlinks && -l $FF_SRC_DIR )
554
    {
555
        Verbose2("do_dir: symlink $FF_SRC_DIR,$FF_DST_DIR");
556
        unless (symlink $FF_SRC_DIR, $FF_DST_DIR  )
557
        {
558
            Error("Failed to create symlink",
559
                  "Src: $FF_SRC_DIR",
560
                  "Dst: $FF_DST_DIR");
561
        }
562
        return 1;
563
    }
564
 
565
    #
566
    # Create the interface dir if it does not exists
567
    #
568
    mkpath ( $FF_DST_DIR, $GBE_VERBOSE, 0775)
569
        unless ( -d $FF_DST_DIR );
570
 
571
    File::Find::find( \&pkgFind2, $FF_SRC_DIR);
572
 
573
    # done
574
    return 1;
575
}
576
 
577
#-------------------------------------------------------------------------------
578
sub pkgFind2
579
#
580
# Description     : Callback function: Process a directory
581
#                   Target name is NOT the same as the source name
582
#
583
#                   The function is called for each file to be processed
584
#                   The name of the file is extracted from $File::Find::name
585
#
586
#                   Processes
587
#                       Directory: Create same directory in the target
588
#                       File     : Link/Copy file to the target
589
#
590
# Inputs          : None passed
591
#                   Globals are used
592
#
593
# Returns         :
594
#
595
#------------------------------------------------------------------------------
596
{
597
    Verbose2("pkgFind2:");
598
 
241 dpurdie 599
    my $item = "$File::Find::name";                     # Full source path
600
    my $dest_path = $FF_DST_DIR . substr ( $item, length ($FF_SRC_DIR) ); # Full destination path
227 dpurdie 601
 
602
    Verbose2 ("---- Src = [$item]");
603
    Verbose2 ("---- Dst = [$dest_path]");
604
    if ( -d $item )
605
    {
606
        #
607
        #   Create a directory
608
        #
609
        mkpath ( $dest_path, $GBE_VERBOSE, 0775) unless( -d $dest_path );
610
 
611
        #
612
        #   Flag the subdir as being processed
613
        #   Prevent multiple copy operations (and warnings)
614
        #
241 dpurdie 615
        my $subdir = substr ( $item, 1 + length ($PKG_ROOT) );
227 dpurdie 616
        $dirs_processed{$subdir} = 1;
617
 
618
    }
619
    else
620
    {
621
        #
622
        #   Copy/Link the file
623
        #
624
        FileLinkCopy ( $item, $dest_path);
625
    }
626
    return 1;
627
}
628
 
629
#-------------------------------------------------------------------------------
630
# Function        : FileLinkCopy
631
#
632
# Description     : Copy a file to a destination
633
#                   If possible create a symlink (Not always be possible)
634
#                   If the file is copied, then chmod it.
635
#
636
# Inputs          : $srcFile                 - Source path (Full)
637
#                   $dstFile                 - Destination path (Full)
638
#
639
#
640
# Globals         : symlinks                - Set if Symlinks are available
641
#                                             Will be cleared if the operation
642
#                                             failed, forcing copy
643
#
644
# Returns         : Nothing
645
#                   Will terminate, with a message, on error
646
#
647
sub FileLinkCopy
648
{
649
    my ($srcFile, $dstFile ) = @_;
650
    my $done;
651
    (my $file = $srcFile) =~ s~.*/~~;       # Filename. Just to be pretty
652
 
653
    #
654
    #   Delete target file. If it exists
331 dpurdie 655
    #       Don't warn if we are allowed to overwrite files
656
    #       This is done for sandbox and local_archive packages
227 dpurdie 657
    #
658
    if ( -f $dstFile )
659
    {
660
        unlink ($dstFile );
331 dpurdie 661
        Message("overwriting existing dpkg_archive item [$file] --> [$dstFile]\n")
662
            unless ( $allow_overwrite );
227 dpurdie 663
    }
664
 
665
    #
666
    #   Try a symlink first
667
    #
668
    if ( $symlinks )
669
    {
670
        Verbose("linking file [$file] --> [$dstFile]...ok");
6133 dpurdie 671
        unlink $dstFile; 
227 dpurdie 672
        unless (symlink ($srcFile, $dstFile)  )
673
        {
674
            #
675
            #   Symlink has failed
676
            #   Flag: Don't symlink anymore
677
            #
678
            $symlinks = 0;
679
            Verbose ("Failed to create symlink from: [$file] --> [$dstFile]");
680
        }
681
        else
682
        {
683
            $done = 1;
684
        }
685
    }
686
 
687
    #
688
    #   Try a copy
689
    #
690
    unless ( $done )
691
    {
692
        if(File::Copy::copy($srcFile, $dstFile))
693
        {
694
            Verbose("copying file [$file] --> [$dstFile]...ok");
695
            CORE::chmod oct("0755"), $dstFile;
696
        }
697
        else
698
        {
699
            Error("copying file [$file] --> [$dstFile]: $!");
700
        }
701
    }
702
}
703
 
704
############ EOF ###############################################################
705