Common issues building CPAN Perl modules to RPMs

Recently I've been compiling several Perl modules for installation on new CentOS 7 machines because we'll be using it to deploy several Catalyst and Mojolicious applications.

The tools

I've mainly used the following tools

  • cpanspec - generates spec files for Perl modules from CPAN available through yum in epel repos:

    sudo yum install cpanspec

  • rpmbuild - build rpm packages, available in rpm-based systems

The cycle

cpanspec -v --packager "My Packager Name" GD::SecurityImage
mv *.spec rpmbuild/SPECS/.; mv *.tar.gz rpmbuild/SOURCES/.
rpmbuild -ba rpmbuild/SPECS/perl-GD-SecurityImage.spec

Common issues - and work-arounds

My main purpose in writing this post was to compile and share the most common issues I ran into while building RPMs from CPAN modules. Hope this helps you and probably my future-self.

Modules using Module::Build::Tiny

(solved in cpanspec master with Leon's PR) CPAN modules that use Module::Build::Tiny instead of the most commonly used Module::Build present the following error:

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
ERROR: Can't create '/usr/local/share/man/man3'
Do not have write permissions on '/usr/local/share/man/man3'
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 at /usr/local/share/perl5/Module/Build/Tiny.pm line 119.

(if you don't, I'd guess you're building the modules with root, which can get you in a lot of trouble)

This is caused by the lack of support by the Tiny module of all the types of arguments available in Module::Build (this is not really a bug but a design option). The arguments passed should have the -- prefix (check Leon's comment on the subject), so, the solution is to edit the spec file and in the sections %build and %install fix the arguments:

--installdirs
--destdir
--create_packlist

Now you can run rpmbuild and everything should be fine.

Packages hidden from PAUSE

For some reason (please tell me why) many distributions hide some namespaces from PAUSE (Perl Authors Upload Server) - HTML::FormHandler example. This causes yum to fail on install, which is quite unpleasant.

Error: Package: perl-HTML-FormHandler-0.40059-1.el7.centos.noarch (/perl-HTML-FormHandler-0.40059-1.el7.centos.noarch)
           Requires: perl(HTML::FormHandler::Meta::Role)
 You could try using --skip-broken to work around the problem
 You could try running: rpm -Va --nofiles --nodigest

A side-effect of hiding the namespace from PAUSE was that neither cpanspec or rpmbuild was able to identify that the HTML::FormHandler::Meta::Role was provided by that same module and listed it as a dependency. You could just add AutoReq: no after the remaining Requires in the spec file but I find that a better work-around is to add:

Provides:       perl(HTML::FormHandler::Meta::Role)

so that rpmbuild and remaining tools now know that this module already has that class. rpmbuild/SPECS/perl-HTML-FormHandler.spec -> Provides

Missing files in MANIFEST - Installed (but unpackaged) file(s) found

Some packages just don't include all the files that they provide (e.g. Test::Harness):

error: Installed (but unpackaged) file(s) found:
   /usr/bin/prove
   /usr/share/man/man1/prove.1.gz

The solution is simple: just double-check that nothing out of the ordinary is there and add the list to the %files spec section. Just copy & paste - that easy.

Bogus paths

Not all module packages are created equal, and some of them, are bogus...

BOGUS PATH DETECTED: PDF-Table-Version_0.9.7/
...
Skipping PDF-Table-0.9.7.tar.gz with 24 path elements!

To fix this issue you'll need to re-package the module but it should be rather easy:

mkdir tmp
cd tmp/
tar xzvf ../PDF-Table-0.9.7.tar.gz
mv PDF-Table-Version_0.9.7/ PDF-Table-0.9.7/
tar czvf PDF-Table-0.9.7.tar.gz PDF-Table-0.9.7
cp PDF-Table-0.9.7.tar.gz ../
cd ..
cpanspec PDF-Table-0.9.7.tar.gz

Now you'll be able to successfully create your .spec file and continue building that module.

Polluted environment - File not found

An error that got me spinning around for hours occurred when rpmbuild could not find some build files, around the lines of:

RPM build errors:
 File not found by glob

I think this is caused by CPAN it might alter your environment with something similar to:

PERL_MM_OPT=INSTALL_BASE=/home/rpmbuild/perl5

As a work-around it's possible to just unset the constant:

unset PERL_LOCAL_LIB_ROOT
unset PERL_MM_OPT
unset INSTALL_BASE
unset PERL_MB_OPT

See also

Changelog

  • Thanks to Thibault for PERL_MB_OPT

6 thoughts on “Common issues building CPAN Perl modules to RPMs”

  1. Polluted environment can be caused by PERL_MB_OPT too. So that would be a fourth line to add:

    unset PERL_LOCAL_LIB_ROOT ;
    unset PERL_MM_OPT ;
    unset INSTALL_BASE ;
    unset PERL_MB_OPT

    1. Thank you and I’m glad that this was useful to you. Added your note to the article.

      Best regards

  2. For the Modules using Module::Build::Tiny problem, I wasn’t quite sure what you were saying to do. After some experimenting, it looks like one just needs to add “–” before any of those 3 arguments that are used, eg, “–installdirs=vendor” instead of “installdirs=vendor”.

    Wish I had found this post earlier! It has some really useful info. Thanks!

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.