develooper Front page | perl.dist | Postings from May 2002

Proposal for a standard RedHat 'spec' file for Perl modules

From:
Johan Vromans
Date:
May 12, 2002 13:34
Subject:
Proposal for a standard RedHat 'spec' file for Perl modules
Message ID:
15582.53686.155217.314717@phoenix.squirrel.nl
=head1 Format of a Perl module RPM 'spec' file

This document proposes a standard format for a SPEC file that can be
used by the RedHat RPM program to generate a pre-built install kit for
Perl modules. It is based on the current RedHat versions 7.x, that
install Perl 5.6.0 or, in newer versions, 5.6.1.

With this SPEC file the Perl module can be installed in the standard
hierarchy where RedHat installs Perl. All RPM functionality can be
used, in particular installation, upgrade, verification and uninstall.

Since most of the SPEC file is pretty standard, it goes without saying
that it can be generated from a rather small description file. This
description file can be used to generate build/install control files
for other distributions (Debian, Suse, ...) as well.

=head2 Preamble

First a one-line summary.

  Summary: Mail::Procmail is an email filter tool

For convenience, define the name of the module in file form (e.g.,
with a dash instead of C<::>), and its path in the module hierarchy. 

  %define module Mail-Procmail
  %define path   Mail

Since this is a Perl module, we prefix the name with C<perl->. In this
example, the name of the RPM kits will be
C<perl-Mail-Procmail-1.03-1.src.rpm> and 
C<perl-Mail-Procmail-1.03-1.noarch.rpm>.

  Name: perl-%{module}

Version and release information. The version corresponds to the (main)
archive that contains this module.

  Version: 1.03
  Release: 1

Now we can define its full URL. The final component of the URL is the
local archive name that contains this module.

  Source: http://www.perl.com/CPAN/modules/by-module/%{path}/%{module}-%{version}.tar.gz

Some general information.

  Copyright: GPL or Artistic
  Group: Mail/Tools
  Packager: Johan Vromans <jvromans@squirrel.nl>

It is important that we keep the build results separated from any
installed packages. Most likely, write access to the install
directories is not even available for the builder of this package.

  BuildRoot: /usr/tmp/%{name}-buildroot

Requirements. Note that usually the requirements are for both
I<building> and I<using> the package. Hence we use C<Requires> and
C<BuildRequires>.

  Requires: perl >= 5.6.0
  Requires: perl(Mail::Internet) == 1.33
  Requires: perl(LockFile::Simple) >= 0.2.5
  BuildRequires: perl >= 5.6.0
  BuildRequires: perl(Mail::Internet) == 1.33
  BuildRequires: perl(LockFile::Simple) >= 0.2.5

The build architecture depends on the module. If it is plain Perl, the
architecture should be C<noarch>. If it contains native code,
the C<BuildArchitectures> directive should be omitted.

  BuildArchitectures: noarch
  

This ends the preamble.

=head2 Sections

The I<description> section describes the purpose of the module. Often
this can be copied from the C<README> file.

  %description
  Procmail is one of the most powerful tools in use on Unix systems to
  filter incoming email. It is, however, rather complicated and
  configuring it can be a pain.
  
  Mail::Procmail is a Perl module that provides procmail-like
  tools that you can use to write your own mail filtering program.


The I<prep> section handles unpacking the source kits. If patches are
required, the can be applied after the C<%setup>.

Note that the rpm-name is perl-I<module>, but the archive will unpack
as I<module>-I<version>. So we use the C<-n> option to C<%setup> to
set the name right.

  %prep
  %setup -n %{module}-%{version}
  

The actual building (and testing!) is straightforward and handled in
the I<build> section.

  %build
  perl Makefile.PL
  make all
  make test
  

To install the module, we use C<$RPM_BUILD_ROOT>, an environment
variable derived from the C<BuildRoot> directive in the preamble.
The real prefix under which Perl is installed is C</usr>, so we use
C<$RPM_BUILD_ROOT/usr> to install.

  %install
  rm -fr $RPM_BUILD_ROOT
  mkdir -p $RPM_BUILD_ROOT/usr
  make install PREFIX=$RPM_BUILD_ROOT/usr
  

As part of the install, a file C<.packlist> is added to the kit, and
C<perllocal.pod> is updated. We do not want these, so remove them
before proceeding.

  # Remove some unwanted files
  find $RPM_BUILD_ROOT -name .packlist -exec rm -f {} \;
  find $RPM_BUILD_ROOT -name perllocal.pod -exec rm -f {} \;
  

RedHat 7.0 and later have the habit of compressing the manual pages.
This happens before the files are packed into the RPM kit. However, we
are going to use C<find> to build the list of files manually so we
need to run the compression manually here.

  # Compress manual pages
  test -x /usr/lib/rpm/brp-compress && /usr/lib/rpm/brp-compress
  

Build the list of files as they should appear in the kit, e.g.,
relative to the installation directory. A glob C<*> in
C<$RPM_BUILD_ROOT> does most of the job. The C<printf> prepends a
slash in front of the file name so it now looks like C</usr/...>
instead of C<usr/...>.

  # Build distribution list
  ( cd $RPM_BUILD_ROOT ; find * -type f -printf "/%p\n" ) > files
  

Finally, gather the files and add the documentation. C<README> and
C<CHANGES> are good candidates for docs. 

  %files -f files
  %defattr (-,root,root)
  %doc README CHANGES examples

=head2 Open issues

We need a way to require that the Perl version upon install can deal
with the pre-built kit. For example, A kit built under Perl 5.6.0 can
be installed under 5.6.1 since the 5.6.0 directories are in the 5.6.1
search path. However, the other way around (installing a 5.6.1 built
module under 5.6.0) does not work and should be detected.

=head2 Extracting the spec file from this document

A simple Perl program, using the Pod::Tree module from CPAN, can
extract the spec data from this document.

 use Pod::Tree;

 my $x = new Pod::Tree;
 $x->load_file(shift);
 $x->walk(\&printcode);

 sub printcode {
     my $node = shift;
     return 1 unless $node->is_verbatim;
     my $text = $node->get_text;
     return 1 unless $text =~ /^  /;
     chomp($text);
     $text =~ s/^  //mg;
     print $text;
     1;
 };



nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About