#!/usr/bin/perl -w
#
#
# makerpm.pl - A Perl script for building binary distributions
# of Perl packages
#
# This script is Copyright (C) 1999 Jochen Wiedmann
# Am Eisteich 9
# 72555 Metzingen
# Germany
#
# E-Mail:
[email protected]
#
# You may distribute under the terms of either the GNU General
# Public License or the Artistic License, as specified in the
# Perl README.
#
use strict;
use Cwd ();
use File::Find ();
use File::Path ();
use File::Spec ();
use Getopt::Long ();
use vars qw($VERSION);
$VERSION = "makerpm 0.1003 22-July-1999, (C) 1999 Jochen Wiedmann";
=pod
=head1 NAME
makerpm - Build binary distributions of Perl packages
=head1 SYNOPSIS
Create a SPECS file:
makerpm --specs --source=<package>-<version>.tar.gz
Apply the SPECS file (which in turn uses makerpm.pl):
rpm -ba <package>-<version>.spec
=head1 DESCRIPTION
The I<makerpm> script is designed for creating binary distributions of
Perl modules, for example RPM packages (Linux) or PPM files (Windows,
running ActivePerl).
=head2 Creating RPM packages
To create a new binary and source RPM, you typically store the tar.gz
file in F</usr/src/redhat/SOURCES> (F</usr/src/packages/SOURCES> in
case of SuSE and F</usr/src/OpenLinux/SOURCES> in case of Caldera) and
do a
makerpm --specs --source=<package>-<version>.tar.gz
This will create a SPECS file in F</usr/src/redhat/SPECS>
(F</usr/src/packages/SOURCES> in case of SuSE and
F</usr/src/OpenLinux/SOURCES> in case of Caldera) which you
can use with
rpm -ba /usr/src/redhat/SPECS/<package>-<version>.spec
If the default behaviour is fine for you, that will do. Otherwise see
the list of options below.
=head2 Creating PPM packages
Not yet implemented
=head2 Command Line Options
Possible command line options are:
=over 8
=item --build
Compile the sources, typically by running
perl Makefile.PL
make
=item --build-root=<dir>
Installation of the Perl package occurs into a separate directory, the
build root directory. For example, a package DBI 1.07 could be installed
into F</var/tmp/DBI-1.07>. Binaries are installed into F<$build_root/usr/bin>
rather than F</usr/bin>, man pages in F<$build_root/usr/man> and so on.
The idea is making the build process really reproducible and building the
package without destructing an existing installation.
You don't need to supply a build root directory, a default name is
choosen.
=item --copyright=<msg>
Set the packages copyright message. The default is
GNU General Public or Artistic License, as specified in the Perl README
=item --debug
Turns on debugging mode. Debugging mode prevents most things from really
being done and implies verbose mode.
=item --help
Print the usage message and exit.
=item --install
Install the sources, typically by running
make install
Installation doesn't occur into the final destination. Instead a
so-called buildroot directory (for example F</var/tmp/build-root>)
is created and installation is adapted relative to that directory.
See the I<--build-root> option for details.
=item --make=<path>
Set path of the I<make> binary; defaults to the location read from Perl's
Config module. L<Config(3)>.
=item --makeopts=<opts>
Set options for running "make" and "make install"; defaults to none.
=item --makemakeropts=<opts>
If you need certain options for running "perl Makefile.PL", this is
your friend. By default no options are set.
=item --mode=<mode>
Set build mode, for example RPM or PPM. By default the build mode
is read from the script name: If you invoke it as I<makerpm>, then
RPM mode is choosen. When running as I<makeppm>, then PPM mode is
enabled.
=item --package-name=<name>
=item --package-version=<version>
Set the package name and version. These options are required for --build and
--install.
=item --prep
Extract the sources and prepare the source directory.
=item --rpm-base-dir=<dir>
=item --rpm-build-dir=<dir>
=item --rpm-source-dir=<dir>
=item --rpm-specs-dir=<dir>
Sets certain directory names related to RPM mode, defaults to
F</usr/src/redhat> (or F</usr/src/packages> on SuSE Linux or
F</usr/src/OpenLinux> on Caldera) F<$base_dir/BUILD>, F<$base_dir/SOURCES>
and F<$base_dir/SPECS>.
=item --rpm-group=<group>
Sets the RPM group; defaults to Development/Languages/Perl.
=item --setup-dir=<dir>
Name of setup directory; defaults to <package>-<version>. The setup
directory is the name of the directory that is created by extracting
the sources. Example: DBI-1.07.
=item --source=<file>
Source file name; used to determine defaults for --package-name and
--package-version. This option is required for --specs and --prep.
=item --summary=<msg>
Summary line; defaults to "The Perl package <name>".
=item --verbose
Turn on verbose mode. Lots of debugging messages are emitted.
=item --version
Print version string and exit.
=back
=cut
package Distribution;
$Distribution::TMP_DIR = '/tmp';
foreach my $dir (qw(/var/tmp /tmp C:/Windows/temp D:/Windows/temp)) {
if (-d $dir) {
$Distribution::TMP_DIR = $dir;
last;
}
}
$Distribution::COPYRIGHT = "Artistic or GNU General Public License,"
. " as specified by the Perl README";
sub new {
my $proto = shift;
my $self = { @_ };
bless($self, ref($proto) || $proto);
if ($self->{'source'} &&
$self->{'source'} =~ /(.*(?:\/|\\))?(.*)-(.+)
(\.(tar\.gz|tgz|zip))$/x) {
$self->{'package-name'} ||= $2;
$self->{'package-version'} ||= $3;
}
$self->{'name'} = $self->{'package-name'}
or die "Missing package name";
$self->{'version'} = $self->{'package-version'}
or die "Missing package version";
$self->{'source_dirs'} ||= [ File::Spec->curdir() ];
$self->{'default_setup_dir'} = "$self->{'name'}-$self->{'version'}";
$self->{'setup-dir'} ||= $self->{'default_setup_dir'};
$self->{'build_dir'} = File::Spec->curdir();
$self->{'make'} ||= $Config::Config{'make'};
$self->{'build-root'} ||= File::Spec->catdir($Distribution::TMP_DIR,
$self->{'setup-dir'});
$self->{'copyright'} ||= $Distribution::COPYRIGHT;
$self->{'summary'} ||= "The Perl package $self->{'name'}";
$self->{'start_perl'} = $self->{'perl-path'}
|| substr($Config::Config{'startperl'}, 2);
$self->{'start_perl'} = undef if $self->{'start_perl'} eq 'undef';
$self;
}
sub Extract {
my $self = shift; my $dir = shift || File::Spec->curdir();
print "Changing directory to $dir\n" if $self->{'verbose'};
chdir $dir || die "Failed to chdir to $dir: $!";
# Look for the source file
my $source = $self->{'source'} || die "Missing source definition";
if (! -f $source) {
foreach my $dir (@{$self->{'source_dirs'}}) {
print "Looking for $source in $dir\n" if $self->{'debug'};
my $s = File::Spec->catfile($dir, $source);
if (-f $s) {
print "Found $source in $dir\n" if $self->{'debug'};
$source = $s;
last;
}
}
}
$dir = $self->{'setup-dir'};
if (-d $dir) {
print "Removing directory $dir" if $self->{'verbose'};
File::Path::rmtree($dir, 0, 0) unless $self->{'debug'};
}
print "Extracting $source\n" if $self->{'verbose'};
eval { require Archive::Tar; require Compress::Zlib; };
if ($@) {
# Archive::Tar is not available; fallback to tar and gzip
my $command = "gzip -cd $source | tar xf -";
my $output = `$command 2>&1`;
die "Archive::Tar and Compress::Zlib are not available\n"
. " and using tar and gzip failed.\n"
. " Command was: $command\n"
. " Output was: $output\n"
if $output;
} else {
die "Failed to extract archive $source: " . Archive::Tar->error()
unless defined(Archive::Tar->extract_archive($source));
}
}
sub Modes {
my $self = shift; my $dir = shift || File::Spec->curdir();
print "Changing directory to $dir\n" if $self->{'verbose'};
chdir $dir || die "Failed to chdir to $dir: $!";
my $handler = sub {
my($dev, $ino, $mode, $nlink, $uid, $gid) = stat;
my $new_mode = 0444;
$new_mode |= 0200 if $mode & 0200;
$new_mode |= 0111 if $mode & 0100;
chmod $new_mode, $_
or die "Failed to change mode of $File::Find::name: $!";
chown 0, 0, $_
or die "Failed to change ownership of $File::Find::name: $!";
};
$dir = File::Spec->curdir();
print "Changing modes in $dir\n" if $self->{'verbose'};
File::Find::find($handler, $dir);
}
sub Prep {
my $self = shift;
my $old_dir = Cwd::cwd();
eval {
my $dir = $self->{'build_dir'};
print "Changing directory to $dir\n" if $self->{'verbose'};
chdir $dir || die "Failed to chdir to $dir: $!";
if (-d $self->{'setup-dir'}) {
print "Removing directory: $self->{'setup-dir'}\n"
if $self->{'verbose'};
File::Path::rmtree($self->{'setup-dir'}, 0, 0);
}
$self->Extract();
$self->Modes($self->{'setup-dir'});
};
my $status = $@;
print "Changing directory to $old_dir\n" if $self->{'verbose'};
chdir $old_dir;
die $@ if $status;
}
sub PerlMakefilePL {
my $self = shift; my $dir = shift || File::Spec->curdir();
print "Changing directory to $dir\n" if $self->{'verbose'};
chdir $dir || die "Failed to chdir to $dir: $!";
my $command = "$^X Makefile.PL " . ($self->{'makemakeropts'} || '');
print "Creating Makefile: $command\n" if $self->{'verbose'};
exit 1 if system $command;
}
sub Make {
my $self = shift;
if (my $dir = shift) {
print "Changing directory to $dir\n" if $self->{'verbose'};
chdir $dir || die "Failed to chdir to $dir: $!";
}
my $command = "$self->{'make'} " . ($self->{'makeopts'} || '');
print "Running Make: $command\n";
exit 1 if system $command;
if ($self->{'runtests'}) {
$command .= " test";
print "Running Make Test: $command\n";
exit 1 if system $command;
}
}
sub ReadLocations {
my %vars;
my $fh = Symbol::gensym();
open($fh, "<Makefile") || die "Failed to open Makefile: $!";
while (my $line = <$fh>) {
# Skip comments and/or empty lines
next if $line =~ /^\s*\#/ or $line =~ /^\s*$/;
if ($line =~ /^\s*(\w+)\s*\=\s*(.*)\s*$/) {
# Variable definition
my $var = $1;
my $val = $2;
$val =~ s/\$(\w)/defined($vars{$1})?$vars{$1}:''/gse;
$val =~ s/\$\((\w+)\)/defined($vars{$1})?$vars{$1}:''/gse;
$val =~ s/\$\{(\w+)\}/defined($vars{$1})?$vars{$1}:''/gse;
$vars{$var} = $val;
}
}
\%vars;
}
sub AdjustPaths {
my $self = shift; my $build_root = shift;
my $adjustPathsSub = sub {
my $f = $_;
return unless -f $f && ! -z _;
my $fh = Symbol::gensym();
open($fh, "+<$f") or die "Failed to open $File::Find::name: $!";
local $/ = undef;
my $contents;
die "Failed to read $File::Find::name: $!"
unless defined($contents = <$fh>);
my $modified;
if ($self->{'start_perl'}) {
$contents =~ s/^\#\!(\S+)/\#\!$self->{'start_perl'}/s;
$modified = 1;
}
if ($contents =~ s/\Q$build_root\E//gs) {
$modified = 1;
}
if ($modified) {
seek($fh, 0, 0) or die "Failed to seek in $File::Find::name: $!";
(print $fh $contents)
or die "Failed to write $File::Find::name: $!";
truncate $fh, length($contents)
or die "Failed to truncate $File::Find::name: $!";
}
close($fh) or die "Failed to close $File::Find::name: $!";
};
File::Find::find($adjustPathsSub, $self->{'build-root'});
}
sub MakeInstall {
my $self = shift;
if (my $dir = shift) {
print "Changing directory to $dir\n" if $self->{'verbose'};
chdir $dir || die "Failed to chdir to $dir: $!";
}
my $locations = ReadLocations();
my $command = "$self->{'make'} " . ($self->{'makeopts'} || '')
. " install";
foreach my $key (qw(INSTALLPRIVLIB INSTALLARCHLIB INSTALLSITELIB
INSTALLSITEARCH INSTALLBIN INSTALLSCRIPT
INSTALLMAN1DIR INSTALLMAN3DIR)) {
my $d = File::Spec->canonpath(File::Spec->catdir($self->{'build-root'},
$locations->{$key}));
$command .= " $key=$d";
}
print "Running Make Install: $command\n" if $self->{'verbose'};
exit 1 if !$self->{'debug'} and system $command;
print "Adjusting Paths in $self->{'build-root'}\n";
$self->AdjustPaths($self->{'build-root'});
my($files, $dirs) = $self->Files($self->{'build-root'});
my $fileList = '';
foreach my $dir (sort keys %$dirs) {
next if $dirs->{$dir};
$fileList .= "%dir $dir\n";
}
foreach my $file (sort keys %$files) {
$fileList .= "$file\n";
}
my($filelist_path, $specs_path) = $self->FileListPath();
if ($filelist_path) {
my $fh = Symbol::gensym();
(open($fh, ">$filelist_path") and (print $fh $fileList)
and close($fh))
or die "Failed to create list of files in $filelist_path: $!";
}
$specs_path;
}
sub Build {
my $self = shift;
my $old_dir = Cwd::cwd();
eval {
my $dir = $self->{'build_dir'};
print "Changing directory to $dir\n" if $self->{'verbose'};
chdir $dir || die "Failed to chdir to $dir: $!";
$self->PerlMakefilePL($self->{'setup-dir'});
$self->Make();
};
my $status = $@;
chdir $old_dir;
die $@ if $status;
}
sub CleanBuildRoot {
my $self = shift; my $dir = shift || die "Missing directory name";
print "Cleaning build root $dir\n" if $self->{'verbose'};
File::Path::rmtree($dir, 0, 0) unless $self->{'debug'};
}
sub Install {
my $self = shift;
my $old_dir = Cwd::cwd();
my $filelist;
eval {
my $dir = $self->{'build_dir'};
print "Changing directory to $dir\n" if $self->{'verbose'};
chdir $dir || die "Failed to chdir to $dir: $!";
$self->CleanBuildRoot($self->{'build-root'});
$filelist = $self->MakeInstall($self->{'setup-dir'});
};
my $status = $@;
chdir $old_dir;
die $@ if $status;
$filelist;
}
package Distribution::RPM;
@Distribution::RPM::ISA = qw(Distribution);
{
my($source_dir, $build_dir, $specs_dir);
sub Init {
my $proto = shift; my $fatal = shift;
if (!$source_dir) {
my $rpm_output = `rpm --showrc`;
my $rpm_version = `rpm --version`;
if ($rpm_version =~ /rpm\s+version\s+2\.+/i) {
foreach my $ref (['specdir', \$specs_dir],
['sourcedir', \$source_dir],
['builddir', \$build_dir]) {
my $var = $ref->[0];
if ($rpm_output =~ /^$var\s+\S+\s+(.*)/m) {
${$ref->[1]} = $1;
}
}
} elsif ($rpm_version =~ /rpm\s+version\s+3\.+/i) {
my $varfunc;
$varfunc = sub {
my $var = shift;
my $val;
if ($rpm_output =~ /^\S+\s+$var\s+(.*)/m) {
$val = $1;
while ($val =~ /\%\{(\S+)\}/) {
my $vr = $1;
my $vl = &$varfunc($vr);
if (defined($vl)) {
$val =~ s/^\%\{\Q$vr\E\}/$vl/gs;
} else {
return undef;
}
}
return $val;
}
return undef;
};
foreach my $ref (['_specdir', \$specs_dir],
['_sourcedir', \$source_dir],
['_builddir', \$build_dir]) {
${$ref->[1]} = &$varfunc($ref->[0]);
}
}
die "Cannot handle your RPM version: " . ($rpm_version || "")
if (!$source_dir or !$specs_dir or !$build_dir) and $fatal;
}
my $base_dir = '/usr/src/redhat';
$source_dir ||= "$base_dir/SOURCES";
$specs_dir ||= "$base_dir/SPECS";
$build_dir ||= "$base_dir/BUILD";
return ($source_dir, $build_dir, $specs_dir);
}
}
sub new {
my $proto = shift;
my $self = $proto->SUPER::new(@_);
($self->{'rpm-source-dir'}, $self->{'rpm-build-dir'},
$self->{'rpm-specs-dir'}) = $proto->Init(1);
$self->{'rpm-group'} ||= 'Development/Languages/Perl';
push(@{$self->{'source_dirs'}}, $self->{'rpm-source-dir'});
$self->{'build_dir'} = $self->{'rpm-build-dir'};
$self;
}
sub Files {
my $self = shift; my $buildRoot = shift;
my(%files, %dirs);
my $findSub = sub {
if (-d $_) {
$dirs{$File::Find::name} ||= 0;
$dirs{$File::Find::dir} = 1;
} elsif (-f _) {
$files{$File::Find::name} = 1;
$dirs{$File::Find::dir} = 1;
} else {
die "Unknown file type: $File::Find::name";
}
};
File::Find::find($findSub, $buildRoot);
# Remove the trailing buildRoot
my(%f, %d);
while (my($key, $val) = each %files) {
$key =~ s/^\Q$buildRoot\E//;
$f{$key} = $val
}
while (my($key, $val) = each %dirs) {
$key =~ s/^\Q$buildRoot\E//;
$d{$key} = $val
}
(\%f, \%d, \%files, \%dirs);
}
sub FileListPath {
my $self = shift;
my $fl = $self->{'setup-dir'} . ".rpmfilelist";
($fl, File::Spec->catdir($self->{'setup-dir'}, $fl));
}
sub Specs {
my $self = shift;
my $old_dir = Cwd::cwd();
eval {
$self->Prep();
$self->Build();
my $filelist = $self->Install();
my($files, $dirs) = $self->Files($self->{'build-root'});
my $specs = <<"EOF";
%define packagename $self->{'name'}
%define packageversion $self->{'version'}
%define release 1
EOF
my $mo = $self->{'makeopts'} || '';
$mo =~ s/\n\t/ /sg;
$specs .= sprintf("%%define makeopts \"%s\"\n",
($mo ? sprintf("--makeopts=%s",
quotemeta($mo)) : ""));
my $mmo = $self->{'makemakeropts'} || '';
$mmo =~ s/\n\t/ /sg;
$specs .= sprintf("%%define makemakeropts \"%s\"\n",
($mmo ? sprintf("--makemakeropts=%s",
quotemeta($mmo)) : ""));
my $setup_dir = $self->{'setup-dir'} eq $self->{'default_setup_dir'} ?
"" : " --setup-dir=$self->{'setup-dir'}";
my $makerpm_path = File::Spec->catdir('$RPM_SOURCE_DIR', 'makerpm.pl');
$makerpm_path = File::Spec->canonpath($makerpm_path) . $setup_dir .
" --source=$self->{'source'}";
$specs .= <<"EOF";
Name: perl-%{packagename}
Version: %{packageversion}
Release: %{release}
Group: $self->{'rpm-group'}
Source: $self->{'source'}
Source1: makerpm.pl
Copyright: $self->{'copyright'}
BuildRoot: $self->{'build-root'}
Provides: perl-%{packagename}
Summary: $self->{'summary'}
EOF
if (my $req = $self->{'require'}) {
$specs .= "Requires: " . join(" ", @$req) . "\n";
}
my $runtests = $self->{'runtests'} ? " --runtests" : "";
$specs .= <<"EOF";
%description
$self->{'summary'}
%prep
$makerpm_path --prep
%build
$makerpm_path --build$runtests %{makeopts} %{makemakeropts}
%install
rm -rf \$RPM_BUILD_ROOT
$makerpm_path --install %{makeopts}
%clean
rm -rf \$RPM_BUILD_ROOT
%files -f $filelist
EOF
my $specs_name = "$self->{'name'}-$self->{'version'}.spec";
my $specs_file = File::Spec->catfile($self->{'rpm-specs-dir'},
$specs_name);
$specs_file = File::Spec->canonpath($specs_file);
print "Creating SPECS file $specs_file\n";
print $specs if $self->{'verbose'};
unless ($self->{'debug'}) {
my $fh = Symbol::gensym();
open(FILE, ">$specs_file") or die "Failed to open $specs_file: $!";
(print FILE $specs) or die "Failed to write to $specs_file: $!";
close(FILE) or die "Failed to close $specs_file: $!";
}
};
my $status = $@;
chdir $old_dir;
die $@ if $status;
}
package main;
sub Mode {
return "RPM" if $0 =~ /rpm$/i;
undef;
}
sub Usage {
my $mode = Mode() || "undef";
my $build_root = File::Spec->catdir($Distribution::TMP_DIR,
"<name>-<version>");
my $start_perl = substr($Config::Config{'startperl'}, 2);
my ($rpm_source_dir, $rpm_build_dir, $rpm_specs_dir) =
Distribution::RPM->Init(1);
print <<EOF;
Usage: $0 <action> [options]
Possible actions are:
--prep Prepare the source directory
--build Compile the sources
--install Install the compiled sources into the buildroot directory
--specs Create a SPECS file by performing the above steps in order
to determine the list of installed files.
Possible options are:
--build-root=<dir> Set build-root directory for installation;
defaults to $build_root.
--copyright=<msg> Set copyright message, defaults to
"GNU General Public License or Artistic
License, as specified in the Perl README".
--debug Turn on debugging mode
--help Print this message
--make=<path> Set "make" path; defaults to $Config::Config{'make'}
--makemakeropts=<opts> Set options for running "perl Makefile.PL";
defaults to none.
--makeopts=<opts> Set options for running "make" and "make
install"; defaults to none.
--mode=<mode> Set build mode, defaults to $mode.
--package-name=<name> Set package name.
--package-version=<name> Set package version.
--perl-path=<path> Perl path to verify in generated scripts;
defaults to $start_perl
--require=<package> Set prerequisite packages. May be used
multiple times.
--runtests By default no "make test" is done. You
can override this with --runtests.
--setup-dir=<dir> Name of setup directory; defaults to
<name>-<version>
--source=<file> Source file name; used to determine defaults
for <name> and <version>.
--summary=<msg> One line desription of the package; defaults
to "The Perl package <name>".
--verbose Turn on verbose mode.
--version Print version string and exit.
Options for RPM mode are:
--rpm-build-dir=<dir> RPM build directory; defaults to
$rpm_build_dir.
--rpm-group=<group> RPM group, default Development/Languages/Perl.
--rpm-source-dir=<dir> RPM source directory; defaults to
$rpm_source_dir.
--rpm-specs-dir=<dir> RPM specs directory; defaults to
$rpm_specs_dir.
$VERSION
EOF
exit 1;
}
{
my %o;
Getopt::Long::GetOptions(\%o, 'build', 'build-root=s', 'copyright=s',
'debug', 'help', 'install', 'make=s',
'makemakeropts=s', 'makeopts=s', 'mode=s',
'package-name=s', 'package-version=s',
'prep', 'require=s@', 'rpm-base-dir=s',
'rpm-build-dir=s', 'rpm-source-dir=s',
'rpm-specs-dir=s', 'rpm-group=s',
'runtests', 'setup-dir=s', 'source=s', 'specs',
'summary=s',
'verbose', 'version=s');
Usage() if $o{'help'};
if ($o{'version'}) { print "$VERSION\n"; exit 1}
$o{'verbose'} = 1 if $o{'debug'};
my $class = 'Distribution::RPM';
if ($o{'mode'}) {
if ($o{'mode'} ne 'rpm') {
die "Unknown mode: $o{'mode'}";
}
}
my $self = $class->new(%o);
if ($o{'prep'}) {
$self->Prep();
} elsif ($o{'build'}) {
$self->Build();
} elsif ($o{'install'}) {
$self->Install();
} elsif ($o{'specs'}) {
$self->Specs();
} else {
die "Missing action";
}
}
__END__
=pod
=head1 INSTALLATION
Before using this script, you need to install the required packages:
C<File::Spec>
If you are using Perl 5.00502 or later, then this package is already
part of your Perl installation. It is recommended to use the
C<Archive::Tar>
C<Compress::Zlib>
packages, if possible.
All of these packages are available on any CPAN mirror, for example
ftp://ftp.funet.fi/pub/languages/perl/CPAN/modules/by-module
To install a package, fetch the corresponding distribution file, for
example
Archive/Archive-Tar-0.21.tar.gz
extract it with
gzip -cd Archive-Tar-0.21.tar.gz
and install it with
cd Archive-Tar-0.21
perl Makefile.PL
make
make test
make install
Alternatively you might try automatic installation via the CPAN module:
cpan (until Perl 5.00503 you need: perl -MCPAN -e shell)
install Archive::Tar
install Compress::Zlib
install File::Spec (only with Perl 5.004 or lower)
=head1 AUTHOR AND COPYRIGHT
This script is Copyright (C) 1999
Jochen Wiedmann
Am Eisteich 9
72555 Metzingen
Germany
E-Mail:
[email protected]
You may distribute under the terms of either the GNU General Public
License or the Artistic License, as specified in the Perl README.
=head1 CPAN
This file is available as a CPAN script. The following subsections are
for CPAN's automatic link generation and not for humans. You can safely
ignore them.
=head2 SCRIPT CATEGORIES
UNIX/System_administration
=head2 README
This script can be used to build RPM or PPM packages automatically.
=head2 PREREQUISITES
This script requires the C<File::Spec> package.
=head1 TODO
=over 8
=item -
Handling of prerequisites by reading PREREQ_PM from the Makefile
=item -
Support for installation and deinstallation scripts
=item -
Make package relocatable
=item -
Support for %description.
=back
=head1 CHANGES
1999-09-13 Jochen Wiedmann <
[email protected]>
* Modes: Fixed the use of ||= instead of |=; thanks to Tim Potter,
Tim Potter <
[email protected]>
* Now using %files -f <listfile>
1999-07-22 Jochen Wiedmann <
[email protected]>
* Now falling back to use of "tar" and "gzip", if Archive::Tar and
Compress::Zlib are not available.
* Added --runtests, suggested by Seth Chaiklin <
[email protected]>.
1999-07-09 Jochen Wiedmann <
[email protected]>
* Now using 'rpm --showrc' to determine RPM's base dirs.
1999-07-01 Jochen Wiedmann <
[email protected]>
* /usr/src/redhat was used rather than $Distribution::RPM::BASE_DIR.
* The AdjustPaths function is now handling files zero size files
properly.
* An INSTALLATION section was added to the docs that describes
the installation of prerequisites.
* A warning for <HANDLE> being possibly "0" is now suppressed with
Perl 5.004.
1999-05-24 Jochen Wiedmann <
[email protected]>
* Added --perl-path and support for fixing startperl in scripts.
Some authors don't know how to fix it. :-(
=head1 SEE ALSO
L<ExtUtils::MakeMaker(3)>, L<rpm(1)>, L<ppm(1)>
=cut