Subversion Repositories DevTools

Rev

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