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
- http://www.openfusion.net/linux/openfusion_rpm_repository - Repositories with several pre-built CPAN modules
- http://www.rpm.org/max-rpm-snapshot/s1-rpm-depend-auto-depend.html
- https://fedoraproject.org/wiki/Perl/Tips?rd=PackagingTips/Perl#Makefile.PL_vs_Build.PL
Changelog
- Thanks to Thibault for
PERL_MB_OPT
Wonderful resource! Thanks a lot!
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
Thank you and I’m glad that this was useful to you. Added your note to the article.
Best regards
Thanks for your comprehensive guide.
Also, for Linux users, the macro %{?perl_default_filter} in the spec file helps remove external requires to VMS & Windows modules.
Reference https://fedoraproject.org/wiki/Packaging:AutoProvidesAndRequiresFiltering
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!
Make that 2 dashes before the arguments!