Archive:PackagingDrafts/Perl

= Perl Packaging =

This document seeks to document the conventions and customs surrounding the proper packaging of perl modules in Fedora. It does not intend to cover all situations, but to codify those practices which have served the Fedora perl community well.

= License tag =

Perl itself is dual licensed, under both the GPL and Artistic licenses. Many perl modules follow this practice; when they do, the license tag should be filled out as "GPL+ or Artistic", not the other way around.

Note also that under the new  license tag guidelines, it's important to specify "GPL+" not just "GPL" for those packages "licensed under the same terms as perl itself."

License: GPL+ or Artistic

= Directory Ownership = As specified in the  general Packaging Guidelines, perl packages are permitted to share ownership of directories.

As an example, assume that  depends on   and installs files into /usr/lib/perl5/vendor_perl/5.10.0/i386-linux-thread-multi/A/B. The base Perl package guarantees that it will own /usr/lib/perl5/vendor_perl/5.10.0/i386-linux-thread-multi for as long as it remains compatible with version 5.10.0, but a future upgrade of the  package may install into (and thus own) /usr/lib/perl5/vendor_perl/5.11.0/i386-linux-thread-multi/A. So the  package needs to own /usr/lib/perl5/vendor_perl/5.10.0/i386-linux-thread-multi/A as well as /usr/lib/perl5/vendor_perl/5.8.8/i386-linux-thread-multi/A/B in order to maintain proper ownership.

= Perl Requires and Provides =

Perl packages use the virtual  naming to indicate a given perl module. Packages should use this methodology, and not require the package name directly. E.g. a package requires the perl module Readonly, a package should not explicitly require the package, but rather  , which the   package provides.

Core modules as buildrequires
Historically, buildrequiring a core module (that is, one provided by the perl package itself) has been frowned upon. However, with the perl/perl-devel split, a number of core modules are now packages seperately from the perl package, and now need to be explicitly buildrequired:


 * perl(CPAN)
 * perl(Ext Utils::Make "; echo $version))

This is to ensure that perl packages have a dependency on a perl which provides the appropriate versioned directory structure (otherwise, the modules won't be found).

Packages that link to libperl
Some packages link to libperl.so, usually to provide embedded perl functionality. All of these packages must also use the versioned MODULE_COMPAT Requires.

Filtering Requires: and Provides
RPM's dependency generator can often throw in additional dependencies and will often think packages provide functionality contrary to reality. To fix this, the dependency generator needs to be overriden so that the additional dependencies can be filtered out. There are two main ways to do this:

In %prep (preferred)
Filtering can be done entirely in the SPEC file, in the %prep section:

cat << \EOF > %{name}-prov %{__perl_provides} $* |\ sed -e '/perl(unwanted_provide)/d' EOF
 * 1) !/bin/sh

%define __perl_provides %{_builddir}/%{name}-%{version}/%{name}-prov chmod +x %{__perl_provides}

cat << \EOF > %{name}-req %{__perl_requires} $* |\ sed -e '/perl(unwanted_require)/d' EOF
 * 1) !/bin/sh

%define __perl_requires %{_builddir}/%{name}-%{version}/%{name}-req chmod +x %{__perl_requires}

External filtering
Or the script can be placed in an external file and referenced from the specfile. This is worse than the above because the full path of the to-be-overridden script needs to be hardcoded into the file, ignoring the system rpmbuild config. It is, however, the method used by a significant number of existing packages.

Source98: filter-provides.sh Source99: filter-requires.sh

%define __perl_provides %{SOURCE98} %define __perl_requires %{SOURCE99} where filter-provides.sh contains: /usr/lib/rpm/perl.prov $* | sed -e '/perl(unwanted_provide)/d' and filter-requires.sh contains: /usr/lib/rpm/perl.req $* | sed -e '/perl(unwanted_require)/d'
 * 1) !/bin/sh
 * 1) !/bin/sh

Manual Requires and Provides
Under some circumstances, RPM's automatic dependency generator can miss dependencies that should be added. This is usually as a result of using language constructs that the dependency script wasn't expecting. An example of this is in the  package, where the following can be found: use base 'Class::Accessor::Fast'; ... use base 'Class::Accessor'; A tell-tale sign of this particular construct is that the package contains a dependency on, but this is not the only situation in which dependencies can be missed. This package needed additional dependencies as follows: Requires: perl(Class::Accessor), perl(Class::Accessor::Fast) In general, it's a good idea to look at the upstream package's documentation for details of other dependencies.

Another similar example of missing requirements can be seen in : package Spreadsheet::WriteExcel::Utility; ... use autouse 'Date::Calc' => qw(Delta_DHMS Decode_Date_EU Decode_Date_US); use autouse 'Date::Manip' => qw(ParseDate Date_Init);

Similarly, it possible to miss Provides:, as was the case in Bug #167797, where the  package failed to Provide:   due to the following construct in   version 1.43: { package DBD::Pg; The usual way of writing this, and what's expected by RPM, is: { package DBD::Pg; So it's wise to examine the Provides: of your packages to check that they are sane and complete. If something is missing, it can be fixed either by using manual Provides: entries, or by patching the source to use a format that RPM can parse correctly.

= URL tag =

For CPAN-based packages the URL tag should use a non-versioned search.cpan.org URL. E.g., if one were packaging the module Net::XMPP, the URL would be:

URL:           http://search.cpan.org/dist/Net-XMPP/

= Testing and Test Suites =

Perl packages typically have a large, healthy test suite. It is policy to run as much of the test suite as possible, subject to the technical limitations of the buildsystem. This means, at the least:


 * All modules required for tests should be listed as a buildrequires
 * Any "optional" tests should be enabled
 * Any modules needed for the tests but not yet in Fedora that could be included in Fedora should also be submitted for review

When to *not* test
There are a couple caveats here:


 * Optional tests do not need to be enabled if they will cause circular build deps
 * Tests which require network or display access should be disabled for the buildsystem, but with a method provided for local builds
 * Tests which do not test package functionality should still be invoked, but their exclusion not be considered a blocker (e.g. Test::Pod::Coverage, Test::Kwalitee and the like)

Additionally, for "meta" packages that provide a common interface to a number of similar modules, it is not necessary to package all of the modules that the package supports so long as at least one module exists to allow the meta package to provide functionality. For instance, the package perl-JSON-Any (JSON::Any) provides a common interface to JSON, JSON::XS, JSON::PC, JSON::Syck and JSON::DWIM; JSON::PC and JSON::DWIM are not currently in Fedora and do not need to be packaged.

Conditionally enabling/disabling tests
One common way to disable a test for mock but enable it locally is to use a  macro test. e.g.:

%check %{?!_with_network_tests: rm t/roster.t } ./Build test

With this construct, an offending test will be removed and not executed, unless "--with network_tests" is passed to  or %_with_network_tests is defined somewhere, e.g. in a user's. This approach preserves the test suite for local builds while working within the technical limitations of the buildsystem.

= Makefile.PL vs Build.PL =

Perl modules typically utilize one of two different buildsystems:


 * Ext Maker
 * Module::Build

The two different styles are easily recognizable: Ext Maker employs the Makefile.PL build file, and is the "classical" approach; Module::Build is a newer approach, with support for things Make,  ,. For a variety of reasons these should not be split off into a -devel package.

= Set inital-cc to 'perl-sig' =

It's common practice to set the Fedora perl SIG mailing list as a member of the initial-cc list for bugzilla. This can be done by adding the user  to the initial CC list.

= cpanspec =

is an excellent little tool to assist in creating Fedora-compliant packages from CPAN-based modules. Its use as a starting point is recommended (but certainly not mandated).