Subversion Repositories DevTools

Rev

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