From Fedora Project Wiki

< Perl

Revision as of 08:14, 27 July 2010 by Ppisar (talk | contribs) (→‎Module version dependencies too much specific: Other possible approach added)

This page is intended to be a repository of "gotchas", and other little quick fixes, that aren't rare but are just uncommon enough that you forget how you did it last time:) This page is NOT part of the official packaging guidelines.

Module version dependencies too much specific

When writing (Build)Requires, you can find the package requires or uses module Foo in very specific version (e.g. use Foo 0.2001;). If you just copy the version to spec file (Requires: perl(Foo) >= 0.2001) you can get unresolved depencecies because packaged perl-Foo's provide shorter version numbers (e.g. perl(Foo) = 0.16, perl(Foo) = 0.20, perl(Foo) = 0.30).

This is caused by the fact that Perl processes version strings as fractional numbers, but RPM as integers (e.g. RPM compares 0 to 0, and 2001 to 30).

There is no right solution. Current practice is to round dependency version up onto the the same number of digits as package version. (e.g. Requires: perl(Foo) >= 0.2001 becomes Requires: perl(Foo) >= 0.21). Of course this approach is meaningful only if current perl-Foo package has at least version 0.21.

If required package does not exist in requested version, the dependency package must be upgraded before (if upstream provides newer (e.g. version 0.30)). If highest upstream provides 0.2001 only, dependency package can be upgraded to provide perl(Foo) = 0.2001, however its maintainer must keep using augmented precision in future versions (e.g. instead of Provides: perl(Foo) = 0.30 she must write Provides: perl(Foo) = 0.3000) not to break RPM version comparison (each newer packager must have EVR string greater than previous one).

In the feature, one could consider different less error-prone approach: Instead of version rounding, one could transform each fraction version digit to next level version integer. E.g. CPAN 12.34 became RPM 12.3.4. This method preserves ordering of fraction numbers, allows extending to more specific numbers and does not request package maintainer to remember number of augmented digits he needs to support in his SPEC file.

Version contains dash

Sometimes it is needed update to development release marked with something like _01. To be 100% sure, you should use in spec file:

%real_version 1.32_01
Version: 1.32.1

Beware dashes in code that could produce warnings if they are not evaluated.

$VERSION = "1.32_01";

This could be solved by adding eval.

$VERSION = "1.32_01";

Makefile.PL vs Build.PL

Perl modules typically utilize one of two different buildsystems:

  • ExtUtils::MakeMaker
  • ExtUtils::Build

The two different styles are easily recognizable: ::MakeMaker employs the Makefile.PL build file, and is the "classical" approach; ::Build is the (relative) new kid on the block, with support for things MakeMaker cannot do. While the ultimate choice of which system to employ is clearly in the hands of upstream, if Build.PL is present in a distribution the packager should employ that build framework, unless there is an awfully good reason otherwise.

See also ["Perl/Build.PL VsMakefile.PL"] .

Tests / build steps requiring network access

This happens from time to time. Some package's tests (or other steps, e.g. signature validation) require network access to return success, but their actual execution isn't essential to the proper building of the package. In these cases, it's often nice to have a simple, transparent, clean way of enabling these steps on your local system (for, e.g., maximum testing), but to have them disabled when actually run through the buildsys/mock.

One easy way to do this is with the "--with" system of conditionals rpmbuild can handle. Running, e.g., "rpmbuild --with network_tests foo.src.rpm" is analagous to including a "--define '_with_network_tests 1'" on the command line. We can test for the existance of that conditional, and take (or not take!) certain actions based on it.

See, e.g., the perl-POE-Component-Client-HTTP spec file for an example.

One way to indicate this inside your spec is to prepend a notice along the lines of:

# some text
# about the change

Then, at the point of the operation, e.g. "make test", that needs to be disabled silently under mock to enable the package build to succeed:

%{?!_with_network_tests:rm t/01* t/02* t/09* t/11* t/50* t/54*}

make test

Now to execute local builds with the network bits enabled, either call rpmbuild with "--with network_tests" or add the line "%_with_network_tests 1" to your ~/.rpmmacros file. Remember to test with _with_network_tests undefined before submitting to the buildsys, to check for syntax errors!

rpmlint errors



Rpmlint returns something to the effect of:

E: perl-WWW-Myspace script-without-shellbang /usr/lib/perl5/vendor_perl/5.8.8/WWW/Myspace/
E: perl-WWW-Myspace script-without-shellbang /usr/lib/perl5/vendor_perl/5.8.8/WWW/Myspace/
E: perl-WWW-Myspace script-without-shellbang /usr/lib/perl5/vendor_perl/5.8.8/WWW/Myspace/


This error is caused by the exec bit being set on one or more .pm files. The solution is to strip the exec bit, for example, in the %install section:

find %{buildroot} -type f -name '*.pm' -exec chmod -x {} 2>/dev/null ';'



W: perl-Class-MakeMethods file-not-utf8 /usr/share/man/man3/Class::MakeMethods::Docs::ReadMe.3pm.gz
W: perl-Class-MakeMethods file-not-utf8 /usr/share/man/man3/Class::MakeMethods::Attribute.3pm.gz


Convert the errant file to UTF-8. Assuming the codepage the file is currently under is ISO-8859-1, this will do the trick (often by reviewers wanted in %prep section, in %build for generated man pages):

cd blib/man3
for i in Docs::ReadMe.3pm Attribute.3pm ; do
iconv --from=ISO-8859-1 --to=UTF-8 Class::MakeMethods::$i > new
mv new Class::MakeMethods::$i

If you are using iconv, you should be BR'ing it, but it's in glibc-common, which is installed anyway...

New Perl specific spec file macros

If you find out that some code snippets repeat in your spec files, you could say: Hey, there should be a macro for that! Then propose the macro for inclusion into /etc/rpm/macros.perl. The file is owned by perl package and is automatically included by rpmbuild tool. Ask perl package maintainer for adding the macro.