Subversion Repositories DevTools

Rev

Rev 1123 | Rev 1127 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
1119 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 package extends the JATS toolset at build time
10
#                 It provides additional directives to the JATS makefiles
11
#                 to simplify the directives.
12
#
13
#                 This directive does all its work at 'build' time
14
#                 It uses makefile.pl directives
15
#
16
# Operation     : This package adds the JATS directive ManifestFiles
17
#                 This is used to create linux manifest files
18
#
19
# Syntax        : ManifestFiles (<platforms>, Options+);
20
#                 See the function header for details
21
#
22
#......................................................................#
23
 
24
require 5.6.1;
25
use strict;
26
use warnings;
27
 
28
#
29
#   Globals
30
#
31
my @Manifests;                      # Manifest entries
1125 alewis 32
my $Manifest_has_version = 1;       # Create Manifest_xxxx by default
1121 dpurdie 33
my %package_dirs;                   # Package dirs discovered and used
1125 alewis 34
my $pkg_subdir;                     # Alternate packaging
1119 dpurdie 35
 
36
#-------------------------------------------------------------------------------
37
# Function        : BEGIN
38
#
39
# Description     : Setup directive hooks
40
#                   Register a function to be called just before we start to
41
#                   generate makefiles. This will be used to process the data
42
#                   collected in all the ManifestFiles directives
43
#
44
# Inputs          : None
45
#
46
# Returns         : None
47
#
48
BEGIN
49
{
50
    RegisterMakefileGenerate (\&ManifestFiles_Generate);
51
}
52
 
53
#-------------------------------------------------------------------------------
54
# Function        : ManifestFiles
55
#
56
# Description     : Create a ManifestFiles entry
57
#
58
# Inputs          : Platform             - Active Platform Selector
59
#                   Options              - One or more options
60
#                       --Name=Name             - Mandatory
61
#                       --Tier=Name             - Mandatory
62
#                       --Architecture=xxxx     - Default actitecture is the current target
63
#                       --Product=yyyy          - Product Family
64
#                       --Debian=BaseName[,--Prod,--Debug,--Arch=xxxx,--Product=yyyy]
65
#                       --MugPackage=Package[,--Subdir=subdir[,subdir]+]
66
#                       --SrcFile=xxx
1125 alewis 67
#                       --SrcFileNoCopy=xxx
1123 dpurdie 68
#                       --Comment=xxx           - Add comment to Manifst
1125 alewis 69
#                       --NoManifestVersion     - Create unversioned Manifest File
70
#                       --PkgSubdir=xxx         - Specifies packaging subdir
1119 dpurdie 71
#
72
# Returns         : Nothing
73
#
74
sub ManifestFiles
75
{
76
    my( $platforms, @elements ) = @_;
77
    Debug2( "ManifestFiles($platforms, @elements)" );
78
    return if ( ! ActivePlatform($platforms) );
79
 
80
    my $name;
81
    my $tier;
82
    my @files;
83
    my $mug_dir;
84
    my $default_arch = $::ScmPlatform;
85
    my $default_prod = '';
86
 
87
    #
88
    #   Collect user options
89
    #
90
    foreach ( @elements )
91
    {
92
        if ( m~^--Name=(.+)~ ) {
93
            if ( $name )
94
            {
95
                ReportError ("ManifestFiles:--Name option is only allowed once");
96
                next;
97
            }
98
            $name = $1;
99
 
100
        } elsif ( m~^--Tier=(.+)~ ) {
101
            if ( $tier )
102
            {
103
                ReportError ("ManifestFiles:--Tier option is only allowed once");
104
                next;
105
            }
106
            $tier = $1;
107
 
1123 dpurdie 108
        } elsif ( m~^--Comment=~ ) {
109
            my $cmt = $_;
110
            $cmt =~ s~.+=~~;
111
            $cmt =~ s~\s*\n\s*~\n~g;
112
            push @files, {'cmt' => $cmt };
113
 
1119 dpurdie 114
        } elsif ( m~^--Debian=(.+)~ ) {
1123 dpurdie 115
            push @files, {'file' => LocateDebianFile($1, $default_arch, $default_prod)};
1119 dpurdie 116
 
117
        } elsif ( m~^--SrcFile=(.+)~ ) {
1123 dpurdie 118
            push @files, {'file' => LocatePreReq($1)};
1119 dpurdie 119
 
1125 alewis 120
        } elsif ( m~^--SrcFileNoCopy=(.+)~ ) {
121
            push @files, {'filenocopy' => $1};
122
 
1119 dpurdie 123
        } elsif ( m~^--MugPackage=(.+)~ ) {
124
            if ( $mug_dir )
125
            {
126
                ReportError ("ManifestFiles:--MugPackage option is only allowed once");
127
                next;
128
            }    
129
            $mug_dir = LocateMugDir($1);
130
 
131
        } elsif ( m/^--Arch(.*)=(.+)/ ) {
132
            $default_arch = $2;
133
 
134
        } elsif ( m/^--Product=(.+)/ ) {
135
            $default_prod = $1;
136
 
1125 alewis 137
        } elsif ( m/^--NoManifestVersion/i ) {
138
            $Manifest_has_version = 0;
139
 
140
        } elsif ( m/^--PkgSubdir=(.+)/i ) {
141
            if ( $pkg_subdir )
142
            {
143
                ReportError ("ManifestFiles:--MugPackage option is only allowed once");
144
                next;
145
            }
146
            $pkg_subdir = $1;
147
 
1119 dpurdie 148
        } else {
149
            ReportError ("ManifestFiles: Unknown option or argument: $_");
150
 
151
        }
152
    }
153
 
154
    #
155
    #   Sanity test the user options
156
    #
157
    ReportError ("ManifestFiles: No name specified")
158
        unless $name;
159
    ReportError ("ManifestFiles: No tier specified")
160
        unless $tier;
161
    ReportError ("ManifestFiles: Cannot mix --Debian/--SrcFile with --MugPackage in one directive")
162
        if ( $mug_dir &&  @files );
163
    ReportError ("ManifestFiles: Must specify files to add to Manifest")
164
        unless ( $mug_dir ||  @files );
165
    ErrorDoExit();
166
 
167
    #
168
    #   Save information for processing at the end of the parsing phase
169
    #   Data collected from ALL the ManifestFiles directives will be collected
170
    #   and processed into one Manifest file
171
    #
172
    my %data;
173
    $data{tier} = $tier;
174
    $data{name} = $name;
175
    $data{files} = \@files;
176
    $data{mugdir} = $mug_dir;
1125 alewis 177
    $data{pkgsubdir} = $pkg_subdir;
1119 dpurdie 178
 
179
    push @Manifests, \%data;
180
    return;
181
 
182
    #-------------------------------------------------------------------------------
183
    # Function        : LocateDebianFile
184
    #
185
    # Description     : Locate a debian file
186
    #                   Internal Function
187
    #
188
    #                   Scan packages for the Debian package specified
189
    #                   The user provides the base name of the package
190
    #                   A Debian Package name has several fields
191
    #                   These are:
192
    #                       1) Base Name - Provided by the user
193
    #                       2) Version - Version will be wildcarded
194
    #                       3) Architecture - Wildcarded. Uses bin/arch directory
195
    #                   
196
    #                   Expect to find Debian Packages in the bin/PLATFORM subdir
197
    #
198
    # Inputs          : Debian base name, complete with suboptions
199
    #
200
    # Returns         : Full path of the file
201
    #
202
    sub LocateDebianFile
203
    {
204
        my ($arg, $arch, $product) = @_;
205
        Verbose("LocateDebianFile: Processing: $arg");
206
 
207
        my @type = qw( P D );
208
        my @debian_file_path;
209
 
210
        #
211
        #   Extract sub-options
212
        #       --Prod[uction]
213
        #       --Debug
214
        #       --Arch[itecture]=yyy
215
        #
216
        my ($base_name, @opts) = split( ',', $arg );
217
        foreach ( @opts )
218
        {
219
            if ( m/^--Arch(.*)=(.+)/ ) {
220
                $arch=$2;
221
            } elsif ( m/^--Product=(.+)/ ) {
222
                $product=$1;
223
            } elsif ( m/^--Prod/ ) {
224
                @type = 'P';
225
            } elsif ( m/^--Debug/ ) {
226
                @type = 'D';
227
            }
228
        }
229
 
230
        #
231
        #   Create a list of products
232
        #   ie: PRODUCT_ARCH
233
        #
234
        my @products;
235
        push @products, $product . '_' . $arch if ( $product );
236
        push @products, $arch;
237
 
238
        #
239
        #   Scan all packages for the specified debian package
240
        #
241
        foreach my $package_dir ( getPackagePaths ('--All') )
242
        {
243
            foreach my $type ( @type )
244
            {
245
                foreach my $prd ( @products )
246
                {
247
                    foreach my $joiner ( qw(/ .) )
248
                    {
249
                        my $dir = "$package_dir/bin$joiner$prd$type";
250
                        Verbose("ManifestFiles: Search in $dir");
251
                        next unless ( -d $dir );
252
                        my @files = glob ( "$dir/${base_name}_*.deb" );
253
                        next unless ( @files );
254
                        push @debian_file_path, @files;
1121 dpurdie 255
                        $package_dirs{$package_dir}{used} = 1;
1119 dpurdie 256
                    }
257
                }
258
            }
259
        }
260
 
261
        ReportError ("Required Debain package not found: $base_name") unless @debian_file_path;
1121 dpurdie 262
        ReportError ("Multiple matching Debian Packages located: $base_name", @debian_file_path ) if ( $#debian_file_path > 0 );
1119 dpurdie 263
        return $debian_file_path[0];
264
    }
265
 
266
    #-------------------------------------------------------------------------------
267
    # Function        : LocateMugDir
268
    #
269
    # Description     : Locate the directory containing the mugfiles
270
    #                   Internal Function
271
    #
272
    # Inputs          : Mufile package, with embedded options
273
    #
274
    # Returns         : Full path
275
    #
276
    sub LocateMugDir
277
    {
278
        my ($mug_package) = @_;
279
 
280
        #
281
        #   Locate the mugfile subdir
282
        #
283
        my $package_name = $mug_package;
284
        my @dirs = 'mug';
285
        my $mug_dir;
286
 
287
        #
288
        #   Extract sub options
289
        #       --Subdir=xxxx,yyyy,zzzz
290
        #
291
        if ( $package_name =~ m/(.*?),--Subdir=(.*)/ )
292
        {
293
            $package_name = $1;
294
            @dirs = split( ',', $2 );
295
        }
296
 
297
        my $package = GetPackageEntry( $package_name );
298
        unless ( $package )
299
        {
300
            ReportError ("ManifestFiles: Package not known to build: $package_name");
301
            return undef;
302
        }
303
 
304
        foreach my $subdir ( @dirs )
305
        {
306
            my $dir = "$package->{'ROOT'}/$subdir";
307
            if ( -d $dir )
308
            {
309
                Warning ("Multiple Mugfile directories located. Only the first will be used",
310
                         "Ignoring: $subdir" )if ( $mug_dir );
311
                $mug_dir = $dir;
312
            }
313
        }
314
        ReportError ("Mugfile directory not found in package: $package_name")
315
            unless $mug_dir;
316
 
317
        return $mug_dir;
318
    }
319
}
320
 
321
#-------------------------------------------------------------------------------
322
# Function        : ManifestFiles_Generate
323
#
324
# Description     : Internal Function
325
#                   Process all the collected data and create directives
326
#                   for the creation of the manifest
327
#
328
#                   This function will be called, just before the Makefile
329
#                   is created. The function will:
330
#                       1) Create the Manifest File
331
#                       2) Package the Manifest File
332
#                       3) Package the manifest file contents
333
#
334
#                   using (mostly) normal makefile.pl directives.
335
#
336
# Inputs          : None
337
#
338
# Returns         : Nothing
339
#
340
sub ManifestFiles_Generate
341
{
342
    Debug ("ManifestFiles_Generate");
343
    Message ("Generating Manifest File");
1123 dpurdie 344
 
345
    #
346
    #   Need at least one Manifest Entry
347
    #
348
    return unless ( @Manifests );
1119 dpurdie 349
#DebugDumpData ( "Manifests", \@Manifests );
350
 
351
    #
1125 alewis 352
    #   Determine the target packaging directory
353
    #   Default is .../mug
354
    #
355
    my $pkgdir = 'mug';
356
    if ( exists $Manifests[0]->{pkgsubdir} )
357
    {
358
        my $subdir = $Manifests[0]->{pkgsubdir};
359
        $pkgdir .= '/' . $subdir;
360
        $pkgdir =~ s~^mug/mug~mug~;
361
    }
362
 
363
    #
1119 dpurdie 364
    #   Create the Manifest File as we process the lists
1125 alewis 365
    #   Place this in the 'lib' directory:
1119 dpurdie 366
    #       - So that it will be deleted on clobber
1123 dpurdie 367
    #       - So that it can be placed in a target-specific subdir
1125 alewis 368
    #       - So that we can have one per makefile.pl
1119 dpurdie 369
    #
370
    Error ("ManifestFiles: Needs local directory specified in build.pl") unless ( $::ScmLocal );
371
 
1125 alewis 372
    my $manifest_dir = "$::ScmPlatform.LIB";
1119 dpurdie 373
    System( "$::GBE_BIN/mkdir -p $manifest_dir" );
374
 
1125 alewis 375
    my $manifest_file = $manifest_dir . '/Manifest';
376
    $manifest_file .= '_' . $::ScmBuildVersion if ( $Manifest_has_version );
377
    ToolsetGenerate( $manifest_file );
1119 dpurdie 378
    Verbose ("ManifestFiles_Generate: File: $manifest_file");
379
 
1125 alewis 380
    PackageFile ('*', $manifest_file, '--Subdir=' . $pkgdir, '--Strip' );
1119 dpurdie 381
 
382
    open (MF, '>', $manifest_file ) || Error ("Cannot create the Manifest file: $manifest_file");
383
 
384
    print_mf ("# PackageName: $::ScmBuildPackage");
385
    print_mf ("# PackageVersion: $::ScmBuildVersion");
386
    print_mf ("# BuildDate: $::CurrentTime");
387
    print_mf ("#");
388
    print_mf ("[Version],$::ScmBuildVersion");
389
    print_mf ("#");
390
 
391
    #
1125 alewis 392
    #   Process each tier in the order presented in the source file
1119 dpurdie 393
    #
1123 dpurdie 394
    my $last_was_comment = 0;
1119 dpurdie 395
    foreach my $entry ( @Manifests )
396
    {
397
    print_mf ("#");
398
 
399
#DebugDumpData ( "Manifest Entry", $entry );
400
 
401
        my $tier = $entry->{tier};
402
        my $name = $entry->{name};
403
 
404
        #
405
        #   Insert all the files that have been specified
406
        #   The user specified order is preserved
407
        #
1123 dpurdie 408
        #   Entries may be either a file or a comment
409
        #   Comments: Merge multiple comments and create blocks
410
        #
411
        #
1119 dpurdie 412
        my @files = @{ $entry->{files} };
1123 dpurdie 413
        foreach my $fentry ( @files )
1119 dpurdie 414
        {
1123 dpurdie 415
            if ( my $cmt = $fentry->{'cmt'} )
416
            {
417
                print_mf ('') unless ( $last_was_comment ) ;
418
                print_mf ( map (('# ' . $_) , split ("\n", $cmt) ));
419
                $last_was_comment = 1;
420
                next;
421
            }
422
 
423
            print_mf ('#') if ( $last_was_comment );
424
            if ( my $file = $fentry->{'file'} )
425
            {
426
                my $base_file = StripDir( $file );
427
                print_mf ("$name,$tier,$base_file");
1125 alewis 428
                PackageFile ('*', $file, '--Subdir=' . $pkgdir, '--Strip' );
1123 dpurdie 429
                $last_was_comment = 0;
430
            }
1125 alewis 431
 
432
            if ( my $file = $fentry->{'filenocopy'} )
433
            {
434
                print_mf ("$name,$tier,$file");
435
                $last_was_comment = 0;
436
            }
1119 dpurdie 437
        }
438
 
439
        #
440
        #   Expand out the entire MUG directory
441
        #   All .mug files in the MUG directory will be added to the manifest
442
        #   The assumption is that the MUG directory has been created by
443
        #   something that knows what its doing
444
        #
445
        if ( my $mugdir = $entry->{mugdir} )
446
        {
447
            foreach my $file ( glob ($mugdir . '/*.mug' ) )
448
            {
449
                next unless ( -f $file );
450
                my $base_file = StripDir($file);
451
                print_mf ("$name,$tier,$base_file");
452
                PackageFile ('*', $file, '--Subdir=mug', '--Strip' );
453
            }
454
        }
455
    }
456
 
457
    #
458
    #   Complete the creation of the Manifest File
459
    #
460
    print_mf ("#");
461
    print_mf ("# End of File");
462
    close MF;
463
    ErrorDoExit();
1121 dpurdie 464
 
465
    #
466
    #   Sanity test of packages that did not provide a debian file
467
    #   Just a hint that something may have been missed
468
    #
469
    my @not_used_packages;
470
    foreach my $package_dir ( getPackagePaths ('--All') )
471
    {
472
        next if ( $package_dir =~ m~/manifest-tool/~ );
473
        unless ( exists $package_dirs{$package_dir}{used} )
474
        {
475
            push @not_used_packages, $package_dir;
476
        }
477
    }
478
    if ( @not_used_packages )
479
    {
480
        Warning ("Packages that did not contribute packages to the manifest:",
481
                  @not_used_packages );
482
    }
483
 
1119 dpurdie 484
    return;
485
 
486
    #-------------------------------------------------------------------------------
487
    # Function        : print_mf
488
    #
489
    # Description     : Internal Function
490
    #                   Print one line to the Manifest File
491
    #                   Checks the length of the line being created
492
    #
493
    # Inputs          : $line
494
    #
495
    # Returns         : 
496
    #
497
 
498
    sub print_mf
499
    {
500
        foreach  ( @_ )
501
        {
502
            ReportError ( "Manifest line too long",
503
                    "Line: $_" ) if ( length ($_) > 79 );
504
            print MF $_ . "\n";
505
        }
506
    }
507
 
508
}
509
 
510
1;