Subversion Repositories DevTools

Rev

Rev 5752 | Rev 5771 | 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
5654 dpurdie 8
# Documents     : MASS-00232 Format of the Linux App Upgrade Manifest File
1119 dpurdie 9
#
10
# Description   : This package extends the JATS toolset at build time
11
#                 It provides additional directives to the JATS makefiles
12
#                 to simplify the directives.
13
#
14
#                 This directive does all its work at 'build' time
15
#                 It uses makefile.pl directives
16
#
17
# Operation     : This package adds the JATS directive ManifestFiles
18
#                 This is used to create linux manifest files
19
#
20
# Syntax        : ManifestFiles (<platforms>, Options+);
21
#                 See the function header for details
22
#
23
#......................................................................#
24
 
25
require 5.6.1;
26
use strict;
27
use warnings;
5649 dpurdie 28
use Digest::file qw(digest_file_hex);
1119 dpurdie 29
 
30
#
31
#   Globals
32
#
33
my @Manifests;                      # Manifest entries
1125 alewis 34
my $Manifest_has_version = 1;       # Create Manifest_xxxx by default
1121 dpurdie 35
my %package_dirs;                   # Package dirs discovered and used
1125 alewis 36
my $pkg_subdir;                     # Alternate packaging
1119 dpurdie 37
 
38
#-------------------------------------------------------------------------------
39
# Function        : BEGIN
40
#
41
# Description     : Setup directive hooks
42
#                   Register a function to be called just before we start to
43
#                   generate makefiles. This will be used to process the data
44
#                   collected in all the ManifestFiles directives
45
#
46
# Inputs          : None
47
#
48
# Returns         : None
49
#
50
BEGIN
51
{
52
    RegisterMakefileGenerate (\&ManifestFiles_Generate);
53
}
54
 
55
#-------------------------------------------------------------------------------
56
# Function        : ManifestFiles
57
#
58
# Description     : Create a ManifestFiles entry
59
#
60
# Inputs          : Platform             - Active Platform Selector
61
#                   Options              - One or more options
62
#                       --Name=Name             - Mandatory
63
#                       --Tier=Name             - Mandatory
64
#                       --Architecture=xxxx     - Default actitecture is the current target
65
#                       --Product=yyyy          - Product Family
66
#                       --Debian=BaseName[,--Prod,--Debug,--Arch=xxxx,--Product=yyyy]
67
#                       --MugPackage=Package[,--Subdir=subdir[,subdir]+]
68
#                       --SrcFile=xxx
1125 alewis 69
#                       --SrcFileNoCopy=xxx
1123 dpurdie 70
#                       --Comment=xxx           - Add comment to Manifst
1125 alewis 71
#                       --NoManifestVersion     - Create unversioned Manifest File
72
#                       --PkgSubdir=xxx         - Specifies packaging subdir
5105 dpurdie 73
#                       --ImportManifest=Package[,--Subdir=subdir,--ReWrite] - Import Manifest from package
5649 dpurdie 74
#                       --Md5                   - Add MD5 checksums to the Manifest File
5767 alewis 75
#                       --Dmf                   - Generate the Device Management Framework
76
#                                                 combined archive ZIP file.
77
#                       --DmfVersion=xxxx       - Generate the Device Management Framework
78
#                                                 combined archive ZIP using a modified
79
#                                                 version number; only for testing!
1119 dpurdie 80
#
81
# Returns         : Nothing
82
#
83
sub ManifestFiles
84
{
85
    my( $platforms, @elements ) = @_;
86
    Debug2( "ManifestFiles($platforms, @elements)" );
87
    return if ( ! ActivePlatform($platforms) );
88
 
89
    my $name;
90
    my $tier;
91
    my @files;
92
    my $mug_dir;
93
    my $default_arch = $::ScmPlatform;
94
    my $default_prod = '';
1129 dpurdie 95
    my $imported_manifest = 0;
5649 dpurdie 96
    my $include_md5 = 0;
5767 alewis 97
    my $generate_dmf = 0;
98
    my $dmf_version = $::ScmBuildVersion;
1119 dpurdie 99
 
100
    #
101
    #   Collect user options
102
    #
103
    foreach ( @elements )
104
    {
105
        if ( m~^--Name=(.+)~ ) {
106
            if ( $name )
107
            {
108
                ReportError ("ManifestFiles:--Name option is only allowed once");
109
                next;
110
            }
111
            $name = $1;
112
 
113
        } elsif ( m~^--Tier=(.+)~ ) {
114
            if ( $tier )
115
            {
116
                ReportError ("ManifestFiles:--Tier option is only allowed once");
117
                next;
118
            }
119
            $tier = $1;
120
 
1123 dpurdie 121
        } elsif ( m~^--Comment=~ ) {
122
            my $cmt = $_;
123
            $cmt =~ s~.+=~~;
124
            $cmt =~ s~\s*\n\s*~\n~g;
125
            push @files, {'cmt' => $cmt };
126
 
1119 dpurdie 127
        } elsif ( m~^--Debian=(.+)~ ) {
1123 dpurdie 128
            push @files, {'file' => LocateDebianFile($1, $default_arch, $default_prod)};
1119 dpurdie 129
 
130
        } elsif ( m~^--SrcFile=(.+)~ ) {
1123 dpurdie 131
            push @files, {'file' => LocatePreReq($1)};
5649 dpurdie 132
 
1125 alewis 133
        } elsif ( m~^--SrcFileNoCopy=(.+)~ ) {
134
            push @files, {'filenocopy' => $1};
5649 dpurdie 135
 
1119 dpurdie 136
        } elsif ( m~^--MugPackage=(.+)~ ) {
137
            if ( $mug_dir )
138
            {
139
                ReportError ("ManifestFiles:--MugPackage option is only allowed once");
140
                next;
5649 dpurdie 141
            }
1119 dpurdie 142
            $mug_dir = LocateMugDir($1);
143
 
144
        } elsif ( m/^--Arch(.*)=(.+)/ ) {
145
            $default_arch = $2;
146
 
147
        } elsif ( m/^--Product=(.+)/ ) {
148
            $default_prod = $1;
149
 
1125 alewis 150
        } elsif ( m/^--NoManifestVersion/i ) {
151
            $Manifest_has_version = 0;
152
 
153
        } elsif ( m/^--PkgSubdir=(.+)/i ) {
154
            if ( $pkg_subdir )
155
            {
1129 dpurdie 156
                ReportError ("ManifestFiles:--PkgSubdir option is only allowed once");
1125 alewis 157
                next;
158
            }
159
            $pkg_subdir = $1;
160
 
1129 dpurdie 161
        } elsif ( m/^--ImportManifest=(.+)/i ) {
5105 dpurdie 162
            my $import_info = ImportManifest($1, $tier, $name);
1129 dpurdie 163
#DebugDumpData("ImportInfo", $import_info );
164
            push @files, {'manifest' => $import_info };
165
 
166
            #
167
            #   Fill in details unless already provided
168
            #
169
            $tier = $import_info->{'tier'} unless ( defined $tier );
170
            $name = $import_info->{'name'} unless ( defined $name );
171
            $imported_manifest = 1;
172
 
5649 dpurdie 173
        } elsif (m/^--Md5/i) {
174
            $include_md5 = 1
175
 
5767 alewis 176
        } elsif (m/^--Dmf/i) {
177
            $generate_dmf = 1
178
 
179
        } elsif ( m/^--DmfVersion=(.+)/ ) {
180
            $generate_dmf = 1;
181
            $dmf_version = $1;
182
 
1119 dpurdie 183
        } else {
184
            ReportError ("ManifestFiles: Unknown option or argument: $_");
185
 
186
        }
187
    }
188
 
189
    #
190
    #   Sanity test the user options
191
    #
192
    ReportError ("ManifestFiles: No name specified")
193
        unless $name;
194
    ReportError ("ManifestFiles: No tier specified")
1129 dpurdie 195
        unless defined ($tier);
1119 dpurdie 196
    ReportError ("ManifestFiles: Cannot mix --Debian/--SrcFile with --MugPackage in one directive")
1129 dpurdie 197
        if ( $mug_dir && (@files || $imported_manifest) );
1119 dpurdie 198
    ReportError ("ManifestFiles: Must specify files to add to Manifest")
1129 dpurdie 199
        unless ( $mug_dir ||  @files || $imported_manifest);
1119 dpurdie 200
    ErrorDoExit();
201
 
202
    #
203
    #   Save information for processing at the end of the parsing phase
204
    #   Data collected from ALL the ManifestFiles directives will be collected
205
    #   and processed into one Manifest file
206
    #
207
    my %data;
208
    $data{tier} = $tier;
209
    $data{name} = $name;
210
    $data{files} = \@files;
211
    $data{mugdir} = $mug_dir;
1125 alewis 212
    $data{pkgsubdir} = $pkg_subdir;
5649 dpurdie 213
    $data{md5} = $include_md5;
5767 alewis 214
    $data{dmf} = $generate_dmf;
215
    $data{arch} = $default_arch;
216
    $data{dmf_version} = $dmf_version;
217
 
1129 dpurdie 218
#DebugDumpData("DirectiveData", \%data );
1119 dpurdie 219
 
220
    push @Manifests, \%data;
221
    return;
222
 
223
    #-------------------------------------------------------------------------------
224
    # Function        : LocateDebianFile
225
    #
226
    # Description     : Locate a debian file
227
    #                   Internal Function
228
    #
229
    #                   Scan packages for the Debian package specified
230
    #                   The user provides the base name of the package
231
    #                   A Debian Package name has several fields
232
    #                   These are:
233
    #                       1) Base Name - Provided by the user
234
    #                       2) Version - Version will be wildcarded
235
    #                       3) Architecture - Wildcarded. Uses bin/arch directory
5649 dpurdie 236
    #
1119 dpurdie 237
    #                   Expect to find Debian Packages in the bin/PLATFORM subdir
238
    #
239
    # Inputs          : Debian base name, complete with suboptions
240
    #
241
    # Returns         : Full path of the file
242
    #
243
    sub LocateDebianFile
244
    {
245
        my ($arg, $arch, $product) = @_;
246
        Verbose("LocateDebianFile: Processing: $arg");
247
 
248
        my @type = qw( P D );
249
        my @debian_file_path;
5649 dpurdie 250
 
1119 dpurdie 251
        #
252
        #   Extract sub-options
253
        #       --Prod[uction]
254
        #       --Debug
255
        #       --Arch[itecture]=yyy
256
        #
257
        my ($base_name, @opts) = split( ',', $arg );
258
        foreach ( @opts )
259
        {
260
            if ( m/^--Arch(.*)=(.+)/ ) {
261
                $arch=$2;
262
            } elsif ( m/^--Product=(.+)/ ) {
263
                $product=$1;
264
            } elsif ( m/^--Prod/ ) {
265
                @type = 'P';
266
            } elsif ( m/^--Debug/ ) {
267
                @type = 'D';
268
            }
269
        }
270
 
271
        #
272
        #   Create a list of products
273
        #   ie: PRODUCT_ARCH
274
        #
275
        my @products;
276
        push @products, $product . '_' . $arch if ( $product );
277
        push @products, $arch;
278
 
279
        #
280
        #   Scan all packages for the specified debian package
281
        #
282
        foreach my $package_dir ( getPackagePaths ('--All') )
283
        {
284
            foreach my $type ( @type )
285
            {
286
                foreach my $prd ( @products )
287
                {
288
                    foreach my $joiner ( qw(/ .) )
289
                    {
290
                        my $dir = "$package_dir/bin$joiner$prd$type";
291
                        Verbose("ManifestFiles: Search in $dir");
292
                        next unless ( -d $dir );
293
                        my @files = glob ( "$dir/${base_name}_*.deb" );
294
                        next unless ( @files );
295
                        push @debian_file_path, @files;
1121 dpurdie 296
                        $package_dirs{$package_dir}{used} = 1;
1119 dpurdie 297
                    }
298
                }
299
            }
300
        }
301
 
5752 dpurdie 302
        ReportError ("Required Debian package not found: $base_name") unless @debian_file_path;
1121 dpurdie 303
        ReportError ("Multiple matching Debian Packages located: $base_name", @debian_file_path ) if ( $#debian_file_path > 0 );
1119 dpurdie 304
        return $debian_file_path[0];
305
    }
306
 
307
    #-------------------------------------------------------------------------------
308
    # Function        : LocateMugDir
309
    #
310
    # Description     : Locate the directory containing the mugfiles
311
    #                   Internal Function
312
    #
313
    # Inputs          : Mufile package, with embedded options
314
    #
315
    # Returns         : Full path
316
    #
317
    sub LocateMugDir
318
    {
319
        my ($mug_package) = @_;
320
 
321
        #
322
        #   Locate the mugfile subdir
323
        #
324
        my $package_name = $mug_package;
325
        my @dirs = 'mug';
326
        my $mug_dir;
327
 
328
        #
329
        #   Extract sub options
330
        #       --Subdir=xxxx,yyyy,zzzz
331
        #
332
        if ( $package_name =~ m/(.*?),--Subdir=(.*)/ )
333
        {
334
            $package_name = $1;
335
            @dirs = split( ',', $2 );
336
        }
337
 
338
        my $package = GetPackageEntry( $package_name );
339
        unless ( $package )
340
        {
341
            ReportError ("ManifestFiles: Package not known to build: $package_name");
342
            return undef;
343
        }
344
 
345
        foreach my $subdir ( @dirs )
346
        {
347
            my $dir = "$package->{'ROOT'}/$subdir";
348
            if ( -d $dir )
349
            {
350
                Warning ("Multiple Mugfile directories located. Only the first will be used",
351
                         "Ignoring: $subdir" )if ( $mug_dir );
352
                $mug_dir = $dir;
353
            }
354
        }
355
        ReportError ("Mugfile directory not found in package: $package_name")
356
            unless $mug_dir;
357
 
358
        return $mug_dir;
359
    }
1129 dpurdie 360
 
361
    #-------------------------------------------------------------------------------
362
    # Function        : ImportManifest
363
    #
364
    # Description     : Import an existing manifest
365
    #
5105 dpurdie 366
    # Inputs          : Args    - PackageName[,Subdir=name,--ReWrite]
367
    #                   tier    - May be null
368
    #                   name    - May be null
1129 dpurdie 369
    #
370
    # Returns         : A hash of data to be used later
371
    #
372
    sub ImportManifest
373
    {
5105 dpurdie 374
        my ($args, $tier, $name) = @_;
1129 dpurdie 375
        my @file_contents;
376
        my @file_list;
377
 
378
        #
379
        #   Locate the mugfile subdir
380
        #
381
        my $package_name = $args;
382
        my @dirs = 'mug';
383
        my $pkg_dir;
384
        my $pkg_root;
385
        my $manifest;
386
        my $first_tier;
387
        my $first_name;
5105 dpurdie 388
        my $rewrite;
1129 dpurdie 389
 
390
        #
391
        #   Extract sub options
392
        #       --Subdir=xxxx,yyyy,zzzz
5105 dpurdie 393
        #       --ReWrite
1129 dpurdie 394
        #
5105 dpurdie 395
        if ( $package_name =~ m/(.*?)(,.*)/ )
1129 dpurdie 396
        {
397
            $package_name = $1;
5105 dpurdie 398
            my @subargs = split(',--', $2);
399
            foreach ( @subargs)
400
            {
401
                next unless (length($_) > 0);
402
                if (m~^Subdir=(.*)~i){
403
                    @dirs = split( ',', $1 );
404
 
405
                } elsif (m~^ReWrite~i) {
406
                    $rewrite = 1;
407
 
408
                } else {
409
                    ReportError("ManifestFiles: Unknown suboption to ImportManifest:" . $_);
410
                }
411
            }
1129 dpurdie 412
        }
413
 
414
        my $package = GetPackageEntry( $package_name );
415
        unless ( $package )
416
        {
417
            ReportError ("ManifestFiles: Package not known to build: $package_name");
418
            return undef;
419
        }
420
 
5105 dpurdie 421
        if (defined ($rewrite) && ( !defined($tier) || !defined($name)))
422
        {
423
            ReportError ("ManifestFiles: ImportManifest. --ReWrite cannot be used unless tier and name are specified");
424
            return undef;
425
        }
426
 
1129 dpurdie 427
        foreach my $subdir ( @dirs )
428
        {
429
            my $dir = "$package->{'ROOT'}/$subdir";
430
            my $root = $package->{'ROOT'};
431
            if ( -d $dir )
432
            {
433
                Warning ("Multiple Package directories located. Only the first will be used",
434
                         "Ignoring: $subdir" )if ( $pkg_dir );
435
                $pkg_dir = $dir;
436
                $pkg_root = $root;
437
            }
438
        }
439
 
5105 dpurdie 440
        unless ($pkg_dir)
441
        {
442
            ReportError ("Package directory not found in package: $package_name");
443
            return undef;
444
        }
445
 
1129 dpurdie 446
        #
447
        #   Determine Manifest File name
448
        #
449
        foreach my $file ( glob ($pkg_dir . '/Manifest*' ) )
450
        {
451
                next unless ( -f $file );
452
                Warning ("Multiple Manifest Files find. Only the first will be used",
453
                         "Using: $manifest",
454
                         "Ignoring: $file" ) if ( $manifest );
455
                $manifest = $file;
456
        }
457
 
5105 dpurdie 458
        unless ($manifest)
459
        {
460
            ReportError ("ImportManifest. No Manifest found: $package_name");
461
            return undef;
462
        }
1129 dpurdie 463
 
5105 dpurdie 464
 
1129 dpurdie 465
        #
466
        #
5649 dpurdie 467
        #
1129 dpurdie 468
        open (MF, '<', $manifest ) || Error ("Cannot open the Manifest file: $manifest", $!);
469
        while ( <MF> )
470
        {
1131 dpurdie 471
            #
5711 kspencer 472
            #   Clean trailing whitespace ( line-feed and new lines )
1131 dpurdie 473
            #   Comment out [Version] data
474
            #
1129 dpurdie 475
            s~\s+$~~;
1131 dpurdie 476
            s~(\s*\[Version])~#$1~;
1129 dpurdie 477
 
478
            #
479
            #   Part lines and determine files
480
            #
481
            next unless ( $_ );
482
            next if ( m~\s*#~ );
483
            next if ( m~\s*\[~ );
484
            my( $aname, $atier, $afile) = split(/\s*\,\s*/, $_);
485
#            print "---------- $_\n";
486
#            print "T: $atier, N:$aname, F:$afile\n";
487
            push @file_list, $afile;
488
 
489
            #
5105 dpurdie 490
            #   Rewrite the name and tier
1129 dpurdie 491
            #
5105 dpurdie 492
            if ($rewrite)
493
            {
494
                $_ = join(',', $name, $tier, $afile);
495
                $first_tier = $tier;
496
                $first_name = $name;
497
            }
498
            else
499
            {
500
                #
501
                #   Capture first tier and name
502
                #
503
                $first_tier = $atier unless ( defined $first_tier );
504
                $first_name = $aname unless ( defined $first_name );
505
            }
1129 dpurdie 506
        }
5105 dpurdie 507
        continue
508
        {
509
            push @file_contents, $_;
510
        }
1129 dpurdie 511
        close MF;
512
 
513
        #
514
        #   Create a hash of data that describes the manifest that has
515
        #   just been read in.
516
        #
517
        $package_dirs{$pkg_root}{used} = 1;
518
        $manifest =~ s~.*/~~;
519
        return { 'contents' => \@file_contents,
520
                  'files' => \@file_list,
521
                  'file_base' => $pkg_dir,
522
                  'manifest' => $manifest,
523
                  'pkg_dir' => $pkg_root,
524
                  'tier' => $first_tier,
525
                  'name' => $first_name,
5105 dpurdie 526
                  'rewrite' => $rewrite,
1129 dpurdie 527
                };
528
    }
1119 dpurdie 529
}
530
 
531
#-------------------------------------------------------------------------------
532
# Function        : ManifestFiles_Generate
533
#
534
# Description     : Internal Function
535
#                   Process all the collected data and create directives
536
#                   for the creation of the manifest
537
#
538
#                   This function will be called, just before the Makefile
539
#                   is created. The function will:
540
#                       1) Create the Manifest File
541
#                       2) Package the Manifest File
542
#                       3) Package the manifest file contents
543
#
544
#                   using (mostly) normal makefile.pl directives.
545
#
546
# Inputs          : None
547
#
548
# Returns         : Nothing
549
#
550
sub ManifestFiles_Generate
551
{
552
    Debug ("ManifestFiles_Generate");
553
    Message ("Generating Manifest File");
1123 dpurdie 554
 
555
    #
556
    #   Need at least one Manifest Entry
557
    #
558
    return unless ( @Manifests );
1119 dpurdie 559
#DebugDumpData ( "Manifests", \@Manifests );
560
 
561
    #
1125 alewis 562
    #   Determine the target packaging directory
563
    #   Default is .../mug
564
    #
565
    my $pkgdir = 'mug';
1129 dpurdie 566
    if ( exists $Manifests[0]->{pkgsubdir} && defined $Manifests[0]->{pkgsubdir} )
1125 alewis 567
    {
568
        my $subdir = $Manifests[0]->{pkgsubdir};
569
        $pkgdir .= '/' . $subdir;
570
        $pkgdir =~ s~^mug/mug~mug~;
571
    }
572
 
573
    #
1119 dpurdie 574
    #   Create the Manifest File as we process the lists
1125 alewis 575
    #   Place this in the 'lib' directory:
1119 dpurdie 576
    #       - So that it will be deleted on clobber
1123 dpurdie 577
    #       - So that it can be placed in a target-specific subdir
1125 alewis 578
    #       - So that we can have one per makefile.pl
1119 dpurdie 579
    #
580
    Error ("ManifestFiles: Needs local directory specified in build.pl") unless ( $::ScmLocal );
581
 
1125 alewis 582
    my $manifest_dir = "$::ScmPlatform.LIB";
1119 dpurdie 583
    System( "$::GBE_BIN/mkdir -p $manifest_dir" );
584
 
1125 alewis 585
    my $manifest_file = $manifest_dir . '/Manifest';
586
    $manifest_file .= '_' . $::ScmBuildVersion if ( $Manifest_has_version );
587
    ToolsetGenerate( $manifest_file );
1119 dpurdie 588
    Verbose ("ManifestFiles_Generate: File: $manifest_file");
5649 dpurdie 589
 
1125 alewis 590
    PackageFile ('*', $manifest_file, '--Subdir=' . $pkgdir, '--Strip' );
1119 dpurdie 591
 
592
    open (MF, '>', $manifest_file ) || Error ("Cannot create the Manifest file: $manifest_file");
593
 
5711 kspencer 594
    binmode (MF);
5767 alewis 595
 
1119 dpurdie 596
    print_mf ("# PackageName: $::ScmBuildPackage");
597
    print_mf ("# PackageVersion: $::ScmBuildVersion");
598
    print_mf ("# BuildDate: $::CurrentTime");
599
    print_mf ("#");
600
    print_mf ("[Version],$::ScmBuildVersion");
601
    print_mf ("#");
602
 
603
    #
1125 alewis 604
    #   Process each tier in the order presented in the source file
1119 dpurdie 605
    #
1123 dpurdie 606
    my $last_was_comment = 0;
1119 dpurdie 607
    foreach my $entry ( @Manifests )
608
    {
1127 alewis 609
    #print_mf ("#");
1119 dpurdie 610
 
611
#DebugDumpData ( "Manifest Entry", $entry );
612
 
613
        my $tier = $entry->{tier};
614
        my $name = $entry->{name};
5649 dpurdie 615
        my $include_md5 = $entry->{md5};
1119 dpurdie 616
 
5767 alewis 617
        if ( $entry->{dmf} )
618
        {
619
        	DmfGenerate($entry);
620
        }
621
 
1119 dpurdie 622
        #
623
        #   Insert all the files that have been specified
624
        #   The user specified order is preserved
625
        #
1123 dpurdie 626
        #   Entries may be either a file or a comment
627
        #   Comments: Merge multiple comments and create blocks
628
        #
629
        #
1119 dpurdie 630
        my @files = @{ $entry->{files} };
1123 dpurdie 631
        foreach my $fentry ( @files )
1119 dpurdie 632
        {
1123 dpurdie 633
            if ( my $cmt = $fentry->{'cmt'} )
634
            {
635
                print_mf ('') unless ( $last_was_comment ) ;
636
                print_mf ( map (('# ' . $_) , split ("\n", $cmt) ));
637
                $last_was_comment = 1;
638
                next;
639
            }
640
 
641
            print_mf ('#') if ( $last_was_comment );
642
            if ( my $file = $fentry->{'file'} )
643
            {
644
                my $base_file = StripDir( $file );
5649 dpurdie 645
                if ($include_md5) {
646
                    my $md5 = digest_file_hex($file, 'MD5');
5654 dpurdie 647
                    print_mf ('--NoCheckLineWidth', "$name,$tier,$base_file,MD5=$md5");
5649 dpurdie 648
                } else {
649
                    print_mf ("$name,$tier,$base_file");
650
                }
1125 alewis 651
                PackageFile ('*', $file, '--Subdir=' . $pkgdir, '--Strip' );
1123 dpurdie 652
                $last_was_comment = 0;
653
            }
1125 alewis 654
 
655
            if ( my $file = $fentry->{'filenocopy'} )
656
            {
657
                print_mf ("$name,$tier,$file");
658
                $last_was_comment = 0;
659
            }
1129 dpurdie 660
 
661
            if ( my $emf = $fentry->{'manifest'} )
662
            {
663
                $last_was_comment = 0;
664
                #
665
                #   Insert the entire manifest
666
                #   Items are:
667
                #        contents
668
                #        files
669
                #        file_base
670
                #        manifest
671
                #
672
#DebugDumpData ( "Embedded Manifest Entry", $emf );
673
                print_mf ( '## Included Manifest: ' .  $emf->{'manifest'}  );
674
                print_mf ($_) foreach  ( @{$emf->{'contents'}} );
675
                PackageFile ('*', $emf->{'file_base'}. '/' . $_, '--Subdir=' . $pkgdir, '--Strip' )foreach  ( @{$emf->{'files'}});;
676
                print_mf ( '## End Included Manifest' );
677
            }
1119 dpurdie 678
        }
679
 
680
        #
681
        #   Expand out the entire MUG directory
682
        #   All .mug files in the MUG directory will be added to the manifest
683
        #   The assumption is that the MUG directory has been created by
684
        #   something that knows what its doing
685
        #
686
        if ( my $mugdir = $entry->{mugdir} )
687
        {
688
            foreach my $file ( glob ($mugdir . '/*.mug' ) )
689
            {
690
                next unless ( -f $file );
691
                my $base_file = StripDir($file);
5654 dpurdie 692
                if ($include_md5) {
693
                    my $md5 = digest_file_hex($file, 'MD5');
694
                    print_mf ('--NoCheckLineWidth', "$name,$tier,$base_file,MD5=$md5");
695
                } else {
696
                    print_mf ("$name,$tier,$base_file");
697
                }
1119 dpurdie 698
                PackageFile ('*', $file, '--Subdir=mug', '--Strip' );
699
            }
700
        }
701
    }
702
 
703
    #
704
    #   Complete the creation of the Manifest File
705
    #
706
    print_mf ("#");
707
    print_mf ("# End of File");
708
    close MF;
709
    ErrorDoExit();
1121 dpurdie 710
 
711
    #
712
    #   Sanity test of packages that did not provide a debian file
713
    #   Just a hint that something may have been missed
714
    #
715
    my @not_used_packages;
716
    foreach my $package_dir ( getPackagePaths ('--All') )
717
    {
718
        next if ( $package_dir =~ m~/manifest-tool/~ );
719
        unless ( exists $package_dirs{$package_dir}{used} )
720
        {
721
            push @not_used_packages, $package_dir;
722
        }
723
    }
724
    if ( @not_used_packages )
725
    {
726
        Warning ("Packages that did not contribute packages to the manifest:",
727
                  @not_used_packages );
728
    }
729
 
1119 dpurdie 730
    return;
731
 
732
    #-------------------------------------------------------------------------------
733
    # Function        : print_mf
734
    #
735
    # Description     : Internal Function
736
    #                   Print one line to the Manifest File
737
    #                   Checks the length of the line being created
738
    #
739
    # Inputs          : $line
740
    #
5649 dpurdie 741
    # Returns         :
1119 dpurdie 742
    #
743
 
744
    sub print_mf
745
    {
5649 dpurdie 746
        my $check_line_width = 1;
747
 
748
        if ($_[0] eq '--NoCheckLineWidth')
749
        {
750
            shift @_;
751
            $check_line_width = 0;
752
        }
753
 
1119 dpurdie 754
        foreach  ( @_ )
755
        {
756
            ReportError ( "Manifest line too long",
5649 dpurdie 757
                    "Line: $_" ) if ( $check_line_width && length ($_) > 79);
1119 dpurdie 758
            print MF $_ . "\n";
759
        }
760
    }
761
}
762
 
5767 alewis 763
# Bring in the DMF build requirements.
764
my $directory;
765
BEGIN {
766
    use File::Spec::Functions qw(rel2abs);
767
    use File::Basename qw(dirname);
768
 
769
    my $path = rel2abs( __FILE__ );
770
    $directory = dirname( $path );
771
}
772
use lib $directory;
773
 
774
use Archive::Zip qw( :ERROR_CODES :CONSTANTS );
775
use JSON;
776
 
777
#-------------------------------------------------------------------------------
778
# Function        : DmfGenerate
779
#
780
# Description     : Import an existing manifest
781
#
782
# Inputs          : entry   - The manifest that is being processed.
783
#
784
# Returns         : Nothing
785
#
786
sub DmfGenerate
787
{
788
    my ($entry) = @_;
789
 
790
    # Get the generation time.
791
    my $gen_time = time();
792
 
793
    my $work_dir = "$::ScmPlatform.BIN/";
794
    System( "$::GBE_BIN/mkdir -p $work_dir" );
795
 
796
    my $name = $entry->{name};
797
    my $version = $entry->{dmf_version};
798
 
799
    # Configure base manifest information.
800
    my %manifest;
801
    $manifest{'name'} = $name;
802
    $manifest{'version'} = $version;
803
    $manifest{'package_name'} = $::ScmBuildPackage;
804
    $manifest{'package_version'} = $::ScmBuildVersion;
805
    $manifest{'datetime'} = localtime($gen_time);
806
    $gen_time *= 1000;  # Make to milliseconds
807
    $manifest{'timestamp'} = $gen_time;
808
    $manifest{'architecture'} = $entry->{arch};
809
    $manifest{'tier'} = $entry->{tier};
810
 
811
    # Process each file.
812
    my @files = @{ $entry->{files} };
813
    my $zip = Archive::Zip->new();
814
    my $i = 0;
815
    foreach my $fentry ( @files )
816
    {
817
        if ( my $file = $fentry->{'file'} )
818
        {
819
        	my $order = $i + 1;
820
            my $base_file = StripDir( $file );
821
            my $publish_file = $name . '_' . $version . '_' . $order . '.aup';
822
            my $aup_file = $work_dir . $publish_file;
823
 
824
            GenerateCesFile($file, $aup_file, 0x3, $gen_time, $publish_file);
825
 
826
            my $file_member = $zip->addFile( $aup_file, $publish_file );
827
 
828
            $manifest{'tasks'}[$i]{'order'} = 1 * $order;
829
            $manifest{'tasks'}[$i]{'filename'} = $base_file;
830
            $manifest{'tasks'}[$i]{'download'} = $publish_file;
831
            if ($base_file =~ /\.sh$/)
832
            {
833
                $manifest{'tasks'}[$i]{'action'} = 'exec-shell';
834
            }
835
            elsif ($base_file =~ /\.deb$/)
836
            {
837
                $manifest{'tasks'}[$i]{'action'} = 'dpkg-install';
838
            }
839
            else
840
            {
841
                ReportError ("Manifest entry $base_file does not have a supported DMF install action");
842
            }
843
 
844
            $i = $i + 1;
845
        }
846
    }
847
 
848
    # Encode and commit the JSON.
849
    my $json_encoder = JSON->new->allow_nonref;
850
    my $json = $json_encoder->pretty->encode( \%manifest );
851
 
852
    my $manifest_filename = $name . '_' . $version;
853
    my $aum_filename = $manifest_filename . '_0.aum';
854
    my $manifest_file = $work_dir . $manifest_filename . '.json';
855
    my $aum_file = $work_dir . $aum_filename;
856
 
857
    # Save our manifest.
858
    open (J, '>', $manifest_file ) || Error ("Cannot create the DMF Manifest file");
859
    binmode (J);
860
    print J $json;
861
 
862
    close J;
863
 
864
    GenerateCesFile($manifest_file, $aum_file, 0x2, $gen_time, $aum_filename);
865
 
866
    $zip->addFile($aum_file, $aum_filename);
867
 
868
    my $zip_filename = $work_dir . $name . '_' . $version . '.zip';
869
    if ( $zip->writeToFileNamed($zip_filename) != AZ_OK )
870
    {
871
        ReportError("DMF ZIP file creation failed");
872
    }
873
    PackageFile('*', $zip_filename, '--Strip');
874
    PackageFile('*', $manifest_file, '--Strip');
875
 
876
}
877
 
878
#-------------------------------------------------------------------------------
879
# Function        : DmfGenerate
880
#
881
# Description     : Import an existing manifest
882
#
883
# Inputs          : src_file     - The input file.
884
#                   dst_file     - The output CES file.
885
#                   content_type - The content type to report.
886
#                   gen_time     - The generation time for the file.
887
#                   filename     - The filename to embed in the CES file.
888
#
889
#
890
# Returns         : Nothing
891
#
892
sub GenerateCesFile
893
{
894
    my ($src_file, $dst_file, $content_type, $gen_time, $filename) = @_;
895
 
896
    open (INF, '<', $src_file ) || Error ("Cannot open file $src_file for reading");
897
    binmode (INF);
898
 
899
    open (OUTF, '>', $dst_file ) || Error ("Cannot open file $dst_file for writing");
900
    binmode (OUTF);
901
 
902
    my $signing_key_name = "";
903
    my $signature_size = 0;
904
    my $format_version = 0xCE500000;
905
    my $compression_method = 0;
906
    my $encryption_method = 0;
907
    my $kek_name = "";
908
    my $encryption_key_size = 0;
909
    my $filename_size = length($filename);
910
 
911
    print OUTF pack("Z32", $signing_key_name);
912
    print OUTF pack("n", $signature_size);
913
    print OUTF pack("N", $format_version);
914
    print OUTF pack("N", $content_type);
915
    print OUTF pack("Q>", $gen_time);
916
    print OUTF pack("N", $compression_method);
917
    print OUTF pack("N", $encryption_method);
918
    print OUTF pack("Z32", $kek_name);
919
    print OUTF pack("n", $encryption_key_size);
920
    print OUTF pack("n", $filename_size);
921
    # Encryption key HERE
922
    print OUTF pack("A$filename_size", $filename);
923
 
924
    my $buf;
925
    while (read(INF,$buf,65536))
926
    {
927
        print OUTF $buf;
928
    }
929
    print OUTF $buf;
930
    close INF;
931
 
932
    # Signature HERE
933
 
934
    # Finish with file.
935
    close OUTF;
936
}
937
 
1119 dpurdie 938
1;