Rev 361 | Rev 6133 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | RSS feed
#! perl######################################################################### Copyright (C) 2006 ERG Limited, All rights reserved## Module name : jats_buildperl.pl# Module type : Makefile system# Compiler(s) : n/a# Environment(s): jats## Description : A utility to assist in building PERL Modules# These are modules that need to be built via there# own Makefile.PL - not to be confused with a JATS file# of the same name.## This script is intended to be called from within a JATS# makefile.## Usage:##......................................................................#require 5.006_001;use strict;use warnings;use Cwd;use FileUtils;use JatsSystem;use JatsError;use ArrayHashUtils;use File::Path;use File::Copy;use File::Find;use Getopt::Long;use Pod::Usage; # required for help supportuse Config;## Initialise and configure some of the used packages#ErrorConfig( 'name' => 'BuildPerl' );SystemConfig ( 'ExitOnError' => 1);InitFileUtils();## Global variables#my $VERSION = "1.0.0"; # Update thismy $opt_debug = $ENV{'GBE_DEBUG'}; # Allow global debugmy $opt_verbose = $ENV{'GBE_VERBOSE'}; # Allow global verbosemy $opt_help = 0;my $opt_manual = 0;my $opt_test = 1;my $opt_clean = 0;my $opt_clean_build = 0;my @MAKE = 'make';my $BASE = Getcwd();my $PKG_DIR;my @PACKAGES;my %PCMDS;my $GBE_MACHTYPE = '';my @PERL5LIB_BASE = split( $ScmPathSep, $ENV{PERL5LIB});## Extract arguments#my $result = GetOptions ("help+" => \$opt_help, # flag, multiple use allowed"manual" => \$opt_manual, # flag, multiple use allowed"verbose+" => \$opt_verbose, # flag, multiple use allowed"test!" => \$opt_test, # Flag, NoFlag"clean!" => \$opt_clean, # Flag, NoFlag"PackageDir=s" => \$PKG_DIR, # String"PerlPackage=s" => \@PACKAGES, # String"MachType=s" => \$GBE_MACHTYPE, # String"clean_build" => \$opt_clean_build, # Flag);## Process help and manual options#pod2usage(-verbose => 0, -message => "Version: $VERSION") if ($opt_help == 1 || ! $result);pod2usage(-verbose => 1) if ($opt_help == 2 );pod2usage(-verbose => 2) if ($opt_manual || ($opt_help > 2));pod2usage(-verbose => 0, -message => "Version: $VERSION") if ( $#ARGV >= 0 );## Sanity Test user input#Error ("No output directory specified") unless ( $PKG_DIR );Error ("No Perl Packages to build" ) unless ( @PACKAGES );Error ("No GBE_MACHTYPE specified" ) unless ( $GBE_MACHTYPE );## Packaging directories# $PKG_DOC - Where to place copyright notices# $PKG_PERL - Where to place perl output#my $PKG_DIR_ABS = AbsPath( $PKG_DIR );my $PKG_DOC = "$PKG_DIR_ABS/doc";my $PKG_PERL= "$PKG_DIR_ABS/pkg/pkg.$GBE_MACHTYPE";## Process PACKAGES and extract the package options#my @PKGS;for my $arg (@PACKAGES){my ($name,@options) = split( ',', $arg );UniquePush \@PKGS, $name;push @{$PCMDS{$name}}, @options;}@PACKAGES = @PKGS;@PKGS = ();Message "======================================================================";Message "Build Perl using the native build method";Message " GBE_MACHTYPE : $GBE_MACHTYPE";Message " Package : $PKG_DIR";for my $ii (@PACKAGES){Message " PerlPackage : $ii";}Message "======================================================================";## Sanity test the Perl Packages#for my $ii (@PACKAGES){Error ("Cannot file package: $ii") unless ( -d $ii );Error ("Perl Package does not contain Makefile.PL") unless ( -f "$ii/Makefile.PL" );}## Remove some 'make' environment variables# The JATS make and the PACKAGE make must not know about each other#foreach my $var (qw ( MAKE MAKEFLAGS MAKEOVERRIDES MAKELEVEL MAKE_MODE CC CXX CPP )){delete $ENV{$var};}## Windows specials#if ( ! $ENV{GBE_UNIX} ){## Must use nmake under windows#@MAKE = ('nmake', '-nologo');## JATS sh fiddles with ComSpec under Windows# Reinstate the original COMSPEC#$ENV{COMSPEC} =~ s~/~\\~g}## Clean the build request# This will be invoked by a JATS clean#if ( $opt_clean_build ){Message "Clean perl build directory";for my $ii (@PACKAGES){if ( -f "$ii/Makefile" ){make( "Cleaning: $ii", $ii, 'clean' );unlink "$ii/Makefile.new", "$ii/Makefile.old";}}exit 0;}## Determine info to extend the library search path# Need to look in site, version and architecture specific directories# into which packages that we are building may have inserted modules#my @lib_search_path;my $pversion = $Config{version};my $parch = $Config{archname};push @lib_search_path, "site_perl/$pversion/$parch";push @lib_search_path, "site_perl/$pversion";push @lib_search_path, "$pversion/$parch";push @lib_search_path, "$pversion";Verbose ('Perl Version List', @lib_search_path );## Create the Makefiles, build and install the artifacts#Message "Invoke package builder";for my $ii (@PACKAGES){## Extend the PERL5LIB so that modules can find the packages that have already# been built. This will satisfy any prerequisites.## Only use top-level directories in the package directory# Don't use lower directories as this confuses the module loader#CalcLibPath();## Generate the Makefile#Message ("Building: $ii", @{$PCMDS{$ii}} );chdir $ii || Error( "Cannot change to directory: $ii");System ( $ENV{GBE_PERL}, 'Makefile.PL', "PREFIX=$PKG_PERL", @{$PCMDS{$ii}} );FixUpMakefile();chdir $BASE;rmtree("$ii/blib");unlink("$ii/pm_to_blib");## make all the default targets#make( "Building: $ii", $ii );make( "Installing: $ii", $ii, 'install' );}## Test# Need to construct a PERL5LIB that will pick up all the .pm files#if ( $opt_test ){Message "Calculate PERL5LIB for testing";CalcLibPath();Message("PERL5LIB: ", split( $ScmPathSep, $ENV{PERL5LIB} ) );Message "Testing Packages";for my $ii (@PACKAGES){if ( -d "$ii/t" || -f "$ii/test.pl" ){make( "Testing: $ii", $ii, 'test' );}else{Message("No Tests found: $ii");}}}## Transfer any COPYRIGHT files to the target package#Message "Transfer COPYRIGHT notice";for my $ii (@PACKAGES){my $file = "$ii/COPYRIGHT";if ( -f $file ){my $package = StripDir ( $ii );my $target = "$PKG_DOC/$package";mkpath ( $target );unlink ( "$target/COPYRIGHT");copy( $file, $target ) || Error ( "Files not copied" );}}## Cleanup the build output#if ( $opt_clean ){Message "Clean build directory";for my $ii (@PACKAGES){make( "Cleaning: $ii", $ii, 'clean' );}}Message "Script complete";exit 0;#-------------------------------------------------------------------------------# Function : FixUpMakefile## Description : Modify the generated Makefile to remove the doc_update recipe# The doc_update step will mess with the perl installed on the# build machine. This is not good.## Inputs :## Returns :#sub FixUpMakefile{Message "Massage Makefile: remove doc_update";my $found = 0;open (MFH, '<', 'Makefile' ) || Error ("Cannot find generated Makefile");open (NFH, '>', 'Makefile.new') || Error ("Cannot create new Makefile");while ( <MFH> ){if ( m/^install ::/ ){$_ =~ s~doc_update~~g;$found = 1;}print NFH $_;}close MFH;close NFH;}#-------------------------------------------------------------------------------# Function : CalcLibPath## Description : Determine a suitale value for PERL5LIB to include# directories in the package area## Note: Do not use ALL subdirs in the package directory# as a recusive devent of the pkg directory will confuse# the module loader## Use top level directories that contain .pm files## Inputs : None## Returns : Nothing# Updates the EnvVar PERL5LIB#sub CalcLibPath{my @dir_list = grep -d $_ , glob( "$PKG_PERL/*" );my @lib_list;foreach my $dir ( @dir_list ){foreach my $subdir ( @lib_search_path ){push @lib_list, "$dir/$subdir"if ( -d "$dir/$subdir" );}push @lib_list, $dir;}$ENV{PERL5LIB} = join( $ScmPathSep, @lib_list, @PERL5LIB_BASE );Verbose ("PERL5LIB: ", split( $ScmPathSep, $ENV{PERL5LIB} ) );}#-------------------------------------------------------------------------------# Function : make## Description : Perform a 'make' in the required target directory## Inputs : $1 - Message# $2 - Target directory# $* - Make arguments## Returns :#sub make{my ($message, $dir, @args ) = @_;Message( $message ) if ( $message );chdir $dir || Error( "Cannot change to directory: $dir");System ( @MAKE , '-f', 'Makefile.new', @args );chdir $BASE;}1;#-------------------------------------------------------------------------------# Documentation#=pod=for htmltoc MAKEUTIL::=head1 NAMEjats_buildperl - Compile up a Perl (CPAN) Package=head1 SYNOPSISperl jats_buildperl [options] (-PerlPackage=path)+Options:-help - brief help message-help -help - Detailed help message-man - Full documentation-[no]test - Test the packages-[no]clean - Clean the build area-PerlPackage=path[,options] - Path to the Perl Package to buildMultiple packages are allowed-PackageDir=path - Root of the output directory-GBE_MACHTYPE=name - Type of the machine being used=head1 OPTIONS=over 8=item B<-help>Print a brief help message and exits.=item B<-help -help>Print a detailed help message with an explanation for each option.=item B<-man>Prints the manual page and exits.=item B<-[no]test>This option may be used to disable the testing phase on all packages. Thedefault operation is to run the tests found in each package.=item B<-[no]clean>This option can be used to disable the process of cleaning the build areaafter each build. The default option is to clean the build area.=item B<-PerlPackage=path[,options]>This option specified the path to a Perl Package. The program expects to findthe file Makefile.PL in this path.The options, if present are provide to the Makefile.pl as arguments.Multiple instances of the one path are compined and the 'options' are merged.This allows multiple options to be specified.Multiple packages can be built at the same time, by using multiple-PerlPackage options. At least one package must be specified.=item B<--PackageDir=path>Mandatory option. This option specifies the root of the packaging directory.The program will place the build artifacts within this directory.=item B<-GBE_MACHTYPE=name>Mandatory option. This option specifies the type of machine on which the packageis being built. This is used to package up the build artifacts.=back=head1 DESCRIPTIONThis program is used internally by Jats to implement the body of the MakePerlModuledirective. The command is not intended to be called by the user.=head1 EXAMPLEMakePerlModule ('*', 'Crypt-Blowfish-2.10','Crypt-Blowfish_PP-1.12','Crypt-CBC-2.22','-notest' );=cut