Subversion Repositories DevTools

Rev

Rev 6133 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
227 dpurdie 1
#! perl
2
########################################################################
6177 dpurdie 3
# COPYRIGHT - VIX IP PTY LTD ("VIX"). ALL RIGHTS RESERVED.
227 dpurdie 4
#
5
# Module name   : jats_buildperl.pl
6
# Module type   : Makefile system
7
# Compiler(s)   : n/a
8
# Environment(s): jats
9
#
10
# Description   : A utility to assist in building PERL Modules
11
#                 These are modules that need to be built via there
12
#                 own Makefile.PL - not to be confused with a JATS file
13
#                 of the same name.
14
#
15
#                 This script is intended to be called from within a JATS
16
#                 makefile.
17
#
18
# Usage:
19
#
20
#......................................................................#
21
 
255 dpurdie 22
require 5.006_001;
227 dpurdie 23
use strict;
24
use warnings;
25
use Cwd;
26
use FileUtils;
27
use JatsSystem;
28
use JatsError;
29
use ArrayHashUtils;
30
use File::Path;
31
use File::Copy;
32
use File::Find;
33
use Getopt::Long;
34
use Pod::Usage;                             # required for help support
35
use Config;
36
 
37
#
38
#   Initialise and configure some of the used packages
39
#
40
ErrorConfig( 'name' => 'BuildPerl' );
41
SystemConfig ( 'ExitOnError' => 1);
42
InitFileUtils();
43
 
44
#
45
#   Global variables
46
#
47
my $VERSION = "1.0.0";                      # Update this
48
my $opt_debug   = $ENV{'GBE_DEBUG'};        # Allow global debug
49
my $opt_verbose = $ENV{'GBE_VERBOSE'};      # Allow global verbose
50
my $opt_help = 0;
51
my $opt_manual = 0;
52
my $opt_test = 1;
53
my $opt_clean = 0;
54
my $opt_clean_build = 0;
6177 dpurdie 55
my $opt_simple;
227 dpurdie 56
 
57
my @MAKE = 'make';
58
my $BASE = Getcwd();
59
my $PKG_DIR;
60
my @PACKAGES;
61
my %PCMDS;
62
my $GBE_MACHTYPE = '';
63
my @PERL5LIB_BASE = split( $ScmPathSep, $ENV{PERL5LIB});
64
 
65
#
66
#   Extract arguments
67
#
68
my $result = GetOptions (
69
                "help+"         => \$opt_help,              # flag, multiple use allowed
70
                "manual"        => \$opt_manual,            # flag, multiple use allowed
71
                "verbose+"      => \$opt_verbose,           # flag, multiple use allowed
72
                "test!"         => \$opt_test,              # Flag, NoFlag
73
                "clean!"        => \$opt_clean,             # Flag, NoFlag
74
                "PackageDir=s"  => \$PKG_DIR,               # String
75
                "PerlPackage=s" => \@PACKAGES,              # String
76
                "MachType=s"    => \$GBE_MACHTYPE,          # String
77
                "clean_build"   => \$opt_clean_build,       # Flag
6177 dpurdie 78
                "simple"        => \$opt_simple,            # Flag
227 dpurdie 79
                );
80
 
81
#
82
#   Process help and manual options
83
#
84
pod2usage(-verbose => 0, -message => "Version: $VERSION") if ($opt_help == 1 || ! $result);
85
pod2usage(-verbose => 1) if ($opt_help == 2 );
86
pod2usage(-verbose => 2) if ($opt_manual || ($opt_help > 2));
87
pod2usage(-verbose => 0, -message => "Version: $VERSION") if ( $#ARGV >= 0 );
88
 
89
#
90
#   Sanity Test user input
91
#
92
Error ("No output directory specified") unless ( $PKG_DIR );
93
Error ("No Perl Packages to build" ) unless ( @PACKAGES );
94
Error ("No GBE_MACHTYPE specified" ) unless ( $GBE_MACHTYPE );
95
 
96
#
97
#   Packaging directories
98
#       $PKG_DOC    - Where to place copyright notices
99
#       $PKG_PERL   - Where to place perl output
100
#
6133 dpurdie 101
my $PKG_DIR_ABS  = FullPath( $PKG_DIR );
227 dpurdie 102
my $PKG_DOC = "$PKG_DIR_ABS/doc";
103
my $PKG_PERL= "$PKG_DIR_ABS/pkg/pkg.$GBE_MACHTYPE";
104
 
105
#
106
#   Process PACKAGES and extract the package options
107
#
108
my @PKGS;
109
for my $arg (@PACKAGES)
110
{
111
    my ($name,@options) = split( ',', $arg );
112
    UniquePush \@PKGS, $name;
113
    push @{$PCMDS{$name}}, @options;
114
}
115
@PACKAGES = @PKGS;
116
@PKGS = ();
117
 
118
 
119
Message    "======================================================================";
120
Message    "Build Perl using the native build method";
121
Message    "     GBE_MACHTYPE : $GBE_MACHTYPE";
6177 dpurdie 122
Message    " Output Structure : " . ( $opt_simple ? 'Simple' : 'Legacy');
227 dpurdie 123
Message    "          Package : $PKG_DIR";
124
for my $ii (@PACKAGES)
125
{
126
    Message    "      PerlPackage : $ii";
127
}
128
Message    "======================================================================";
129
 
130
#
131
#   Sanity test the Perl Packages
132
#
133
for my $ii (@PACKAGES)
134
{
135
    Error ("Cannot file package: $ii") unless ( -d $ii );
136
    Error ("Perl Package does not contain Makefile.PL") unless ( -f "$ii/Makefile.PL" );
137
}
138
 
139
#
140
#   Remove some 'make' environment variables
141
#   The JATS make and the PACKAGE make must not know about each other
142
#
369 dpurdie 143
foreach my $var (qw ( MAKE MAKEFLAGS MAKEOVERRIDES MAKELEVEL MAKE_MODE CC CXX CPP ))
227 dpurdie 144
{
145
    delete $ENV{$var};
146
}
147
 
148
#
149
#   Windows specials
150
#
151
if ( ! $ENV{GBE_UNIX}   )
152
{
153
    #
154
    #   Must use nmake under windows
155
    #
6133 dpurdie 156
    @MAKE = ('nmake', '-nologo', 'MAKE=nmake');
227 dpurdie 157
 
158
    #
159
    #   JATS sh fiddles with ComSpec under Windows
160
    #   Reinstate the original COMSPEC
161
    #
162
    $ENV{COMSPEC} =~ s~/~\\~g
163
}
164
 
6133 dpurdie 165
if ($opt_verbose)
166
{
167
    push @MAKE, 'NOECHO='; 
168
}
169
 
227 dpurdie 170
#
171
#   Clean the build request
172
#   This will be invoked by a JATS clean
173
#
174
if ( $opt_clean_build )
175
{
176
    Message "Clean perl build directory";
177
    for my $ii (@PACKAGES)
178
    {
179
        if ( -f "$ii/Makefile" )
180
        {
181
            make( "Cleaning: $ii", $ii, 'clean' );
182
            unlink  "$ii/Makefile.new", "$ii/Makefile.old";
183
        }
184
    }
185
    exit 0;
186
}
187
 
188
#
189
#   Determine info to extend the library search path
190
#   Need to look in site, version and architecture specific directories
191
#   into which packages that we are building may have inserted modules
192
#
193
my @lib_search_path;
194
my $pversion = $Config{version};
195
my $parch = $Config{archname};
196
 
197
push @lib_search_path, "site_perl/$pversion/$parch";
198
push @lib_search_path, "site_perl/$pversion";
199
push @lib_search_path, "$pversion/$parch";
200
push @lib_search_path, "$pversion";
201
 
202
Verbose ('Perl Version List', @lib_search_path );
203
 
204
#
205
#   Create the Makefiles, build and install the artifacts
206
#
207
Message "Invoke package builder";
208
for my $ii (@PACKAGES)
209
{
210
 
211
    #
212
    #   Extend the PERL5LIB so that modules can find the packages that have already
213
    #   been built. This will satisfy any prerequisites.
214
    #
215
    #   Only use top-level directories in the package directory
216
    #   Don't use lower directories as this confuses the module loader
217
    #
218
    CalcLibPath();
219
 
220
    #
221
    #   Generate the Makefile
6177 dpurdie 222
    #   Force installation into a known (and simple) structure
227 dpurdie 223
    #
224
    Message ("Building: $ii", @{$PCMDS{$ii}} );
225
    chdir $ii || Error( "Cannot change to directory: $ii");
6177 dpurdie 226
 
227
    my @opts;
228
    if ($opt_simple)
229
    {
230
        push @opts,
231
            'INSTALLPRIVLIB=$(PREFIX)/share/perl',
232
            'INSTALLSITELIB=$(PREFIX)/share/perl',
233
            'INSTALLVENDORLIB=$(PREFIX)/share/perl',
234
            'INSTALLARCHLIB=$(PERLPREFIX)/lib/perl',
235
            'INSTALLSITEARCH=$(PREFIX)/lib/perl',
236
            'INSTALLVENDORARCH=$(PREFIX)/lib/perl',
237
            'INSTALLBIN=$(PERLPREFIX)/bin',
238
            'INSTALLSITEBIN=$(PREFIX)/bin',
239
            'INSTALLVENDORBIN=$(PREFIX)/bin',
240
            'INSTALLSCRIPT=$(PERLPREFIX)/bin',
241
            'INSTALLSITESCRIPT=$(PREFIX)/bin',
242
            'INSTALLVENDORSCRIPT=$(PREFIX)/bin',
243
            'INSTALLMAN1DIR=$(PERLPREFIX)/share/man/man1',
244
            'INSTALLSITEMAN1DIR=$(PREFIX)/share/man/man1',
245
            'INSTALLVENDORMAN1DIR=$(PREFIX)/share/man/man1',
246
            'INSTALLMAN3DIR=$(PERLPREFIX)/share/man/man3',
247
            'INSTALLSITEMAN3DIR=$(PREFIX)/share/man/man3',
248
            'INSTALLVENDORMAN3DIR=$(PREFIX)/share/man/man3';
249
 
250
    }
251
 
252
    System ( $ENV{GBE_PERL},  
253
            'Makefile.PL', 
254
            "PREFIX=$PKG_PERL", 
255
            @opts,
256
            @{$PCMDS{$ii}} );
227 dpurdie 257
    FixUpMakefile();
258
    chdir $BASE;
259
 
260
    rmtree("$ii/blib");
261
    unlink("$ii/pm_to_blib");
262
 
263
    #
264
    #   make all the default targets
265
    #
266
    make( "Building: $ii", $ii );
267
    make( "Installing: $ii", $ii, 'install' );
268
}
269
 
270
#
271
#   Test
272
#   Need to construct a PERL5LIB that will pick up all the .pm files
273
#
274
if ( $opt_test )
275
{
276
    Message "Calculate PERL5LIB for testing";
277
    CalcLibPath();
278
    Message("PERL5LIB: ", split( $ScmPathSep, $ENV{PERL5LIB} ) );
279
 
280
    Message "Testing Packages";
281
    for my $ii (@PACKAGES)
282
    {
283
        if ( -d "$ii/t" || -f "$ii/test.pl" )
284
        {
285
            make( "Testing: $ii", $ii, 'test' );
286
        }
287
        else
288
        {
289
            Message("No Tests found: $ii");
290
        }
291
    }
292
}
293
 
294
#
295
#   Transfer any COPYRIGHT files to the target package
296
#
297
Message "Transfer COPYRIGHT notice";
298
for my $ii (@PACKAGES)
299
{
300
    my $file = "$ii/COPYRIGHT";
301
    if ( -f $file )
302
    {
303
        my $package = StripDir ( $ii );
304
        my $target = "$PKG_DOC/$package";
305
        mkpath ( $target );
306
        unlink ( "$target/COPYRIGHT");
307
        copy( $file, $target ) || Error ( "Files not copied" );
308
    }
309
}
310
 
311
#
312
#   Cleanup the build output
313
#
314
if ( $opt_clean )
315
{
316
    Message "Clean build directory";
317
    for my $ii (@PACKAGES)
318
    {
319
        make( "Cleaning: $ii", $ii, 'clean' );
320
    }
321
}
322
 
323
Message "Script complete";
324
exit 0;
325
 
326
 
327
#-------------------------------------------------------------------------------
328
# Function        : FixUpMakefile
329
#
330
# Description     : Modify the generated Makefile to remove the doc_update recipe
331
#                   The doc_update step will mess with the perl installed on the
332
#                   build machine. This is not good.
333
#
334
# Inputs          :
335
#
336
# Returns         :
337
#
338
sub FixUpMakefile
339
{
340
    Message "Massage Makefile: remove doc_update";
341
    my $found = 0;
342
    open (MFH, '<', 'Makefile' )    || Error ("Cannot find generated Makefile");
343
    open (NFH, '>', 'Makefile.new') || Error ("Cannot create new Makefile");
344
    while ( <MFH> )
345
    {
346
        if ( m/^install ::/ )
347
        {
348
            $_ =~ s~doc_update~~g;
349
            $found = 1;
350
        }
351
        print NFH $_;
352
    }
353
    close MFH;
354
    close NFH;
355
 
356
}
357
 
358
#-------------------------------------------------------------------------------
359
# Function        : CalcLibPath
360
#
361
# Description     : Determine a suitale value for PERL5LIB to include
362
#                   directories in the package area
363
#
364
#                   Note: Do not use ALL subdirs in the package directory
365
#                         as a recusive devent of the pkg directory will confuse
366
#                         the module loader
367
#
368
#                   Use top level directories that contain .pm files
369
#
370
# Inputs          : None
371
#
372
# Returns         : Nothing
373
#                   Updates the EnvVar PERL5LIB
374
#
375
sub CalcLibPath
376
{
377
    my @dir_list =  grep -d $_ , glob( "$PKG_PERL/*" );
378
    my @lib_list;
379
 
380
    foreach my $dir ( @dir_list )
381
    {
382
        foreach my $subdir ( @lib_search_path )
383
        {
384
            push @lib_list, "$dir/$subdir"
385
                if ( -d "$dir/$subdir" );
386
        }
387
        push @lib_list, $dir;
388
    }
389
 
390
    $ENV{PERL5LIB} = join( $ScmPathSep, @lib_list, @PERL5LIB_BASE );
391
    Verbose ("PERL5LIB: ", split( $ScmPathSep, $ENV{PERL5LIB} ) );
392
}
393
 
394
#-------------------------------------------------------------------------------
395
# Function        : make
396
#
397
# Description     : Perform a 'make' in the required target directory
398
#
399
# Inputs          : $1  - Message
400
#                   $2  - Target directory
401
#                   $*  - Make arguments
402
#
403
# Returns         :
404
#
405
sub make
406
{
407
    my ($message, $dir, @args ) = @_;
408
 
409
    Message( $message ) if ( $message );
410
 
411
    chdir $dir || Error( "Cannot change to directory: $dir");
412
    System ( @MAKE , '-f', 'Makefile.new', @args );
413
    chdir $BASE;
414
}
415
 
416
1;
417
 
418
#-------------------------------------------------------------------------------
419
#   Documentation
420
#
421
 
422
=pod
423
 
361 dpurdie 424
=for htmltoc    MAKEUTIL::
425
 
227 dpurdie 426
=head1 NAME
427
 
428
jats_buildperl - Compile up a Perl (CPAN) Package
429
 
430
=head1 SYNOPSIS
431
 
432
perl jats_buildperl [options] (-PerlPackage=path)+
433
 
434
 Options:
435
    -help                       - brief help message
436
    -help -help                 - Detailed help message
437
    -man                        - Full documentation
438
    -[no]test                   - Test the packages
439
    -[no]clean                  - Clean the build area
440
    -PerlPackage=path[,options] - Path to the Perl Package to build
441
                                  Multiple packages are allowed
442
    -PackageDir=path            - Root of the output directory
443
    -GBE_MACHTYPE=name          - Type of the machine being used
6177 dpurdie 444
    -Simple                     - SImple output directory structure
227 dpurdie 445
 
446
=head1 OPTIONS
447
 
448
=over 8
449
 
450
=item B<-help>
451
 
452
Print a brief help message and exits.
453
 
454
=item B<-help -help>
455
 
456
Print a detailed help message with an explanation for each option.
457
 
458
=item B<-man>
459
 
460
Prints the manual page and exits.
461
 
462
=item B<-[no]test>
463
 
464
This option may be used to disable the testing phase on all packages. The
465
default operation is to run the tests found in each package.
466
 
467
=item B<-[no]clean>
468
 
469
This option can be used to disable the process of cleaning the build area
470
after each build. The default option is to clean the build area.
471
 
472
=item B<-PerlPackage=path[,options]>
473
 
474
This option specified the path to a Perl Package. The program expects to find
475
the file Makefile.PL in this path.
476
 
477
The options, if present are provide to the Makefile.pl as arguments.
478
 
479
Multiple instances of the one path are compined and the 'options' are merged.
480
This allows multiple options to be specified.
481
 
482
Multiple packages can be built at the same time, by using multiple
483
-PerlPackage options. At least one package must be specified.
484
 
485
=item B<--PackageDir=path>
486
 
487
Mandatory option. This option specifies the root of the packaging directory.
488
The program will place the build artifacts within this directory.
489
 
490
=item B<-GBE_MACHTYPE=name>
491
 
492
Mandatory option. This option specifies the type of machine on which the package
493
is being built. This is used to package up the  build artifacts.
494
 
6177 dpurdie 495
=item B<-Simple>
496
 
497
Recommended. This option will simplify the output directory structure and make it uniform 
498
between build platforms.
499
 
361 dpurdie 500
=back
227 dpurdie 501
 
502
=head1 DESCRIPTION
503
 
504
This program is used internally by Jats to implement the body of the MakePerlModule
505
directive. The command is not intended to be called by the user.
506
 
507
=head1 EXAMPLE
508
 
509
 MakePerlModule ('*', 'Crypt-Blowfish-2.10',
510
                      'Crypt-Blowfish_PP-1.12',
511
                      'Crypt-CBC-2.22',
512
                      '-notest' );
513
 
514
=cut
515