Subversion Repositories DevTools

Rev

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