How to build Perl module rpm file with cpanspec on RHEL/CentOS Linux

I am using CentOS/RHEL 7.x heavily, and many needed CPAN modules missing. I want to distribute Perl modules from CPAN to 100s of VMs and bare metal servers. Unfortunately running cpanm Module::Name OR perl -MCPAN -e 'install Module::Name' is not an option. Is there any way to build RPM packages with rpmbuild for specific Perl module on a CentOS/RHEL 7.x server? What’s the easiest way to install a missing Perl module using the yum command?

The rpmbuild command is used to build both binary and source software packages for CentOS/RHEL based system. A rpm package consists of an archive of files and meta-data used to install and erase the archive files. The meta-data includes helper scripts, file attributes, and descriptive information about the package. You need to use cpanspec command that will generate a spec file to build a rpm from a CPAN-style Perl module distribution.

How to install cpanspec

Type the following cpanspec command. First turn on EPEL repo for RHEL/CentOS 7 (see how to turn on EPEL repo for RHEL/CentOS 6 here):
$ sudo yum install
$ sudo yum install cpanspec perl-ExtUtils-CBuilder perl-Module-Build perl-Test-Simpl

How to install compilers to build Perl module

You need setup a basic development environment with the following packages on a CentOS Enterprise Linux or Red Hat Enterprise Linux version 7. This is needed to build rpm files for Perl CPAN modules.
$ sudo yum group install "Development Tools"
See “CentOS / RHEL 7: Install GCC (C and C++ Compiler) and Development Tools” for more info.

How to use cpanspec

The syntax is pretty simple:
cpanspec moduleNameHere
cpanspec [options] moduleNameHere

How to build Perl module rpm file with cpanspec on RHEL/CentOS

Let us say we need a perl interface to the lchown() system call, on platforms that support it. For demo purpose I am going to build Lchown Perl CPAN module rpm:
$ cpanspec --follow --packager 'Vivek Gite ' -v Lchown


  • --follow – Add build dependencies to the list of modules to process
  • --packager – The name and email address of the packager. Overrides the %packager macro in “~/.rpmmacros”.
  • -v – Be more verbose
  • Lchown – Generate a spec file to build a rpm from a CPAN-style Perl module distribution for Lchown

You should see two file as follows in the current directory using the ls command:
$ ls *.tar.gz *.spec
Lchown-1.01.tar.gz perl-Lchown.spec

A perl-Lchown.spec file describes to rpmbuild how to build and package the Lchown Perl module. You can view it with a text editor or cat command:
$ cat perl-Lchown.spec
Sample outputs:

Name:           perl-Lchown
Version:        1.01
Release:        1%{?dist}
Summary:        Use the lchown(2) system call from Perl
License:        GPL+ or Artistic
Group:          Development/Libraries
BuildRoot:      %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
BuildRequires:  perl(ExtUtils::CBuilder)
BuildRequires:  perl(Module::Build)
BuildRequires:  perl(Test::More)
Requires:       perl(:MODULE_COMPAT_%(eval "`%{__perl} -V:version`"; echo $version))
Provides a perl interface to the lchown() system call, on platforms that
support it.
%setup -q -n Lchown-%{version}
%{__perl} Build.PL installdirs=vendor optimize="$RPM_OPT_FLAGS"
./Build install destdir=$RPM_BUILD_ROOT create_packlist=0
find $RPM_BUILD_ROOT -type f -name '*.bs' -size 0 -exec rm -f {} \;
find $RPM_BUILD_ROOT -depth -type d -exec rmdir {} 2>/dev/null \;
%{_fixperms} $RPM_BUILD_ROOT/*
./Build test
%doc Changes README
* Thu Feb 01 2018 Vivek Gite <> 1.01-1
- Specfile autogenerated by cpanspec 1.78.

Prepare the source directory

Create ~/rpmbuild/SOURCES/ directory using mkdir command:
$ mkdir -pv ~/rpmbuild/SOURCES/
Copy the Lchown-1.01.tar.gz source tar ball into the SOURCES directory, so rpmbuild command can locate it using the cp command:
$ cp -v ~/Lchown-1.01.tar.gz ~/rpmbuild/SOURCES/

Build the RPM with rpmbuild

Run the following command:
$ rpmbuild -ba perl-Lchown.spec
Sample outputs:

Executing(%prep): /bin/sh -e /var/tmp/rpm-tmp.BMSMjM
+ umask 022
+ cd /home/vivek/rpmbuild/BUILD
+ cd /home/vivek/rpmbuild/BUILD
+ rm -rf Lchown-1.01
+ /usr/bin/gzip -dc /home/vivek/rpmbuild/SOURCES/Lchown-1.01.tar.gz
+ /usr/bin/tar -xf -
+ '[' 0 -ne 0 ']'
+ cd Lchown-1.01
+ /usr/bin/chmod -Rf a+rX,u+w,g-w,o-w .
+ exit 0
Executing(%build): /bin/sh -e /var/tmp/rpm-tmp.Fwa6hu
+ umask 022
+ cd /home/vivek/rpmbuild/BUILD
Checking for unpackaged file(s): /usr/lib/rpm/check-files /home/vivek/rpmbuild/BUILDROOT/perl-Lchown-1.01-1.el7.centos.x86_64
Wrote: /home/vivek/rpmbuild/SRPMS/perl-Lchown-1.01-1.el7.centos.src.rpm
Wrote: /home/vivek/rpmbuild/RPMS/x86_64/perl-Lchown-1.01-1.el7.centos.x86_64.rpm
Wrote: /home/vivek/rpmbuild/RPMS/x86_64/perl-Lchown-debuginfo-1.01-1.el7.centos.x86_64.rpm
Executing(%clean): /bin/sh -e /var/tmp/rpm-tmp.tSg0XZ
+ umask 022
+ cd /home/vivek/rpmbuild/BUILD
+ cd Lchown-1.01
+ rm -rf /home/vivek/rpmbuild/BUILDROOT/perl-Lchown-1.01-1.el7.centos.x86_64
+ exit 0

The -ba option to the rpmbuild command tell to build source and binary packages from given .spec file. You should see lots of output. At the bottom you of the screen you should list of files created:

Wrote: /home/vivek/rpmbuild/SRPMS/perl-Lchown-1.01-1.el7.centos.src.rpm
Wrote: /home/vivek/rpmbuild/RPMS/x86_64/perl-Lchown-1.01-1.el7.centos.x86_64.rpm
Wrote: /home/vivek/rpmbuild/RPMS/x86_64/perl-Lchown-debuginfo-1.01-1.el7.centos.x86_64.rpm

Now all you have to do is install perl-Lchown-1.01-1.el7.centos.x86_64.rpm file:
$ sudo yum install ~/rpmbuild/RPMS/x86_64/perl-Lchown-1.01-1.el7.centos.x86_64.rpm
You may want to sing RPM with gpg for security (provided that you have GPG configured with a key):
$ rpmsign --addsign ~/rpmbuild/RPMS/x86_64/perl-Lchown-1.01-1.el7.centos.x86_64.rpm
You can now push your RPM file(s) using a private yum repo or automation tool such as chef or ansible to any number of VMs/cloud servers.


🐧 Get the latest tutorials on Linux, Open Source & DevOps via RSS feed or Weekly email newsletter.

🐧 0 comments... add one

CategoryList of Unix and Linux commands
Disk space analyzersdf ncdu pydf
File Managementcat cp mkdir tree
FirewallAlpine Awall CentOS 8 OpenSUSE RHEL 8 Ubuntu 16.04 Ubuntu 18.04 Ubuntu 20.04
Network UtilitiesNetHogs dig host ip nmap
OpenVPNCentOS 7 CentOS 8 Debian 10 Debian 8/9 Ubuntu 18.04 Ubuntu 20.04
Package Managerapk apt
Processes Managementbg chroot cron disown fg jobs killall kill pidof pstree pwdx time
Searchinggrep whereis which
User Informationgroups id lastcomm last lid/libuser-lid logname members users whoami who w
WireGuard VPNAlpine CentOS 8 Debian 10 Firewall Ubuntu 20.04
0 comments… add one

Leave a Reply

Your email address will not be published.

Use HTML <pre>...</pre> for code samples. Still have questions? Post it on our forum