Subversion Repositories DevTools

Rev

Rev 5709 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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