2023-04-24 13:10:25 +08:00
|
|
|
Packaging of Perl Modules
|
|
|
|
=========================
|
2023-04-24 15:37:59 +08:00
|
|
|
|
|
|
|
This file explains the packaging guidelines that I am attempting to
|
|
|
|
follow for Free Libre Open Source Software (FLOSS) Perl modules from
|
|
|
|
[CPAN](https://metacpan.org/)
|
|
|
|
|
2023-04-28 18:08:59 +08:00
|
|
|
These guidelines are for RPM packages, not for installing modules via
|
|
|
|
the native CPAN installer (which also works).
|
2023-04-24 15:37:59 +08:00
|
|
|
|
|
|
|
|
|
|
|
YJL RPM Macros for Perl
|
|
|
|
-----------------------
|
|
|
|
|
|
|
|
The RPM Macros used when building Perl and Perl modules are defined
|
|
|
|
in [`/usr/lib/rpm/macros.d/macros.perl`](SOURCES/rpm-macros-perl-5.36)
|
|
|
|
which is owned by the `perl-devel` package.
|
|
|
|
|
|
|
|
For packaging modules from CPAN, the following macros are used:
|
|
|
|
|
|
|
|
* `%{perl5_vendorlib}` --- The base directory for RPM packaged perl
|
|
|
|
modules that are architecture independent.
|
|
|
|
* `%{perl5_vendorarch}` --- The base directory for RPM packaged perl
|
|
|
|
modules with compiled components.
|
|
|
|
* `%{perl5_API}` --- Used in YJL to limit a `noarch` package to the
|
|
|
|
series of Perl it was packaged for (e.g. 5.38.x)
|
|
|
|
* `%{perl5_ABI}` --- Used in YJL to limit a binary package to the
|
|
|
|
series of Perl it was packaged for.
|
|
|
|
* `%{perl5_cpanlic}` --- Used in YJL for the handful of cases where
|
2023-04-28 18:08:59 +08:00
|
|
|
a Perl packages specifies a license but does not actually include
|
2023-04-24 15:37:59 +08:00
|
|
|
the license in the package tarball.
|
|
|
|
|
2023-04-24 18:07:12 +08:00
|
|
|
### Non-Perl Specific Macros
|
|
|
|
|
|
|
|
Virtually every Perl module has tests that should be run, but to avoid
|
|
|
|
circular dependency issues one should *always* be able to build a Perl
|
|
|
|
module without running the tests.
|
|
|
|
|
2023-04-28 18:08:59 +08:00
|
|
|
The `%{runtests}` macro is a Boolean macro that YJL uses to determine
|
2023-04-24 18:07:12 +08:00
|
|
|
whether or not tests should be run.
|
|
|
|
|
|
|
|
To conditionally run tests, I use the following in my `~/.rpmmacros`
|
|
|
|
file:
|
|
|
|
|
|
|
|
%runtests fubar
|
|
|
|
|
|
|
|
When I do not wish to run tests, I just comment that out my
|
|
|
|
`~/.rpmmacros` file.
|
|
|
|
|
|
|
|
More information on that macro can be found at
|
|
|
|
(00-NON-STANDARD-MACROS.md#the-runtests-macro)
|
|
|
|
|
|
|
|
The `%{_fixperms}` macro is a standard RPM macro that expands to
|
|
|
|
`/usr/bin/chmod -Rf a+rX,u+w,g-w,o-w`
|
|
|
|
|
|
|
|
Perl likes to install stuff without the write permission bit set, and
|
|
|
|
that causes problems when RPM wants to strip a binary library.
|
|
|
|
|
|
|
|
That macro is only needed for binary modules and is a standard part of
|
|
|
|
RPM itself.
|
|
|
|
|
2023-04-24 15:37:59 +08:00
|
|
|
### Spec File Portability Note
|
|
|
|
|
2023-04-24 18:07:12 +08:00
|
|
|
Of the five YJL Perl specific RPM macros, `%{perl5_API}`, `%{perl5_ABI}`,
|
|
|
|
and `%{perl5_cpanlic}` should be used in such a way that the spec file
|
|
|
|
still builds on other systems where they will not be defined.
|
2023-04-24 15:37:59 +08:00
|
|
|
|
2023-04-24 18:07:12 +08:00
|
|
|
For `%{perl5_vendorlib}` and `%{perl5_vendorlib}`, to build a YJL Perl
|
|
|
|
module RPM spec file on another system the user will have to define those
|
|
|
|
macros on their system. Usually just adding the following to a
|
|
|
|
`~/.rpmmacros` file will suffice:
|
2023-04-24 15:37:59 +08:00
|
|
|
|
|
|
|
%perl5_vendorlib %{perl_vendorlib}
|
|
|
|
%perl5_vendorarch %{perl_vendorarch}
|
|
|
|
|
|
|
|
While I could have just used the more standard convention for the
|
|
|
|
purpose, it is my opinion a good idea to restrict the macros to the
|
|
|
|
Perl5 just so that it makes it easier to have a future Perl 7 installed
|
|
|
|
on the same system as Perl 5.
|
|
|
|
|
|
|
|
Scripting language specific macros should be versioned, and I chose
|
|
|
|
to not follow the incorrect mainstream naming scheme just because that
|
|
|
|
is what all (or most) distributions do.
|
|
|
|
|
2023-04-28 18:08:59 +08:00
|
|
|
Other distributions LOVE to have distribution-specific Perl and Python
|
|
|
|
macros that are difficult to identify what it is they are trying to do,
|
|
|
|
making building their RPM spec files a nightmare on another system, so
|
|
|
|
I do not feel bad about this deviation one bit *especially* since this
|
2023-04-24 18:07:12 +08:00
|
|
|
deviation from common practice is cake to work around.
|
2023-04-24 15:37:59 +08:00
|
|
|
|
2023-04-24 18:07:12 +08:00
|
|
|
|
|
|
|
First Line Of The RPM Spec File
|
|
|
|
-------------------------------
|
2023-04-24 15:37:59 +08:00
|
|
|
|
|
|
|
The very first line should define the CPAN name of the module in a macro
|
2023-04-28 18:08:59 +08:00
|
|
|
name `cpanname`. Usually it is the Perl module but replacing any
|
2023-04-24 15:37:59 +08:00
|
|
|
occurrences `::` with a `-`, e.g. the Perl module `Test::More::UTF8`
|
|
|
|
would have a CPAN name of `Test-More-UTF8`.
|
|
|
|
|
|
|
|
Precisely, it has the name of the tarball on CPAN without the version
|
|
|
|
and tarball extension.
|
|
|
|
|
|
|
|
Example first line:
|
|
|
|
|
|
|
|
%global cpanname Text-Template
|
|
|
|
|
|
|
|
|
|
|
|
RPM Spec File Metadata Tags
|
|
|
|
---------------------------
|
|
|
|
|
|
|
|
The RPM spec file `Name:` metadata field then contains the following:
|
|
|
|
|
|
|
|
Name: perl-%{cpanname}
|
|
|
|
|
|
|
|
For the RPM spec file `Summary:` metadata field, it is best to use the
|
|
|
|
summary provided after the __NAME__ heading on the CPAN web page for
|
|
|
|
the Perl module. For example:
|
|
|
|
|
|
|
|
Summary: Expand template text with embedded Perl
|
|
|
|
|
|
|
|
When a Perl module only contains text files as opposed to binary files
|
|
|
|
(this is usually the case), the Perl module package __MUST__ be defined
|
|
|
|
as a `noarch` package:
|
|
|
|
|
|
|
|
BuildArch: noarch
|
|
|
|
|
|
|
|
While not strictly required, I do like to have an empty line between
|
|
|
|
that first group of metadata tags and the next group.
|
|
|
|
|
|
|
|
For the RPM spec file `Group:` metadata tag, how to categorize groups
|
|
|
|
in YJL has not yet been determined. Generally for the present I am
|
|
|
|
just using `Development/Libraries` as such:
|
|
|
|
|
|
|
|
Group: Development/Libraries
|
|
|
|
|
2023-04-28 18:08:59 +08:00
|
|
|
To me that does not quite feel right as most Perl modules are both
|
|
|
|
development *and* run-time libraries. I will figure that out later.
|
2023-04-24 15:37:59 +08:00
|
|
|
It seems on my CentOS 7.9.2009 (running the ancient Perl 5.16.3)
|
|
|
|
that many Perl modules just do not specify a group. Anyway...
|
|
|
|
|
2023-04-24 18:07:12 +08:00
|
|
|
For the RPM spec file `License:` metadata tag, the
|
|
|
|
[SPDX License Identifier](https://spdx.org/licenses/) should be used.
|
|
|
|
|
|
|
|
Many (but not) Perl modules on CPAN specify they use the same license
|
2023-04-28 18:08:59 +08:00
|
|
|
as Perl5 itself, and on CPAN those packages are labeled as
|
2023-04-24 18:07:12 +08:00
|
|
|
|
|
|
|
License: perl_5
|
|
|
|
|
|
|
|
Perl 5 is dual-license, giving the user the option of using either the
|
|
|
|
GPL 1.0 (or newer) or the Perl Artistic license.
|
|
|
|
|
|
|
|
The correct way using SPDX to specify the `License:` metadata tag in
|
|
|
|
those cases:
|
|
|
|
|
|
|
|
License: GPL-1.0-or-later or Artistic-1.0-Perl
|
|
|
|
|
|
|
|
For the RPM spec file `URL:` metadata tag, it should point to the URL
|
|
|
|
on CPAN for the module. For example:
|
|
|
|
|
|
|
|
URL: https://metacpan.org/pod/Text::Template
|
|
|
|
|
|
|
|
The RPM spec file `SOURCE:` metadata tag needs to point to the CPAN
|
|
|
|
link for the module source tarball:
|
|
|
|
|
|
|
|
Source0: https://cpan.metacpan.org/authors/id/M/MS/MSCHOUT/%{cpanname}-%{version}.tar.gz
|
|
|
|
|
|
|
|
The path on `cpan.metacpan.org` will differ according to the author of
|
|
|
|
the package.
|
|
|
|
|
|
|
|
|
|
|
|
BuildRequires
|
|
|
|
-------------
|
|
|
|
|
|
|
|
Every Perl module needs
|
|
|
|
|
|
|
|
BuildRequires: perl-devel
|
|
|
|
|
|
|
|
That is the package that owns the file defining the Perl specific RPM
|
|
|
|
macros that are used when building a Perl module.
|
|
|
|
|
|
|
|
Any package that builds using `Makefile.PL` (most of them) will need
|
|
|
|
|
|
|
|
BuildRequires: perl(ExtUtils::MakeMaker) >= 6.76
|
|
|
|
|
|
|
|
The reason for that, some of the options that are passed to `Makefile.PL`
|
|
|
|
are not defined in earlier versions of `ExtUtils::MakeMaker`.
|
|
|
|
|
|
|
|
Of course if the package itself specifies an even newer version of
|
|
|
|
`ExtUtils::MakeMaker` is needed, then specify the newer version.
|
|
|
|
|
|
|
|
Note the version of `ExtUtils::MakeMaker` in Perl 5.36.1 is 7.64, for
|
|
|
|
YJL itself that version requirement will always be met regardless of
|
|
|
|
whether or not it is specified, but it still needs to be specified so
|
2023-04-28 18:08:59 +08:00
|
|
|
that people trying to build the package for another distribution (such
|
|
|
|
as CentOS 7 where it is only at version 6.68 if not updated).
|
2023-04-24 18:07:12 +08:00
|
|
|
|
|
|
|
### Determining Build Requirements
|
|
|
|
|
|
|
|
For other build requirements, a packager needs to distinguish between
|
|
|
|
those that are actually needed to build the module and those that are
|
|
|
|
only needed if running tests.
|
|
|
|
|
|
|
|
For `noarch` Perl modules that make use of `Makefile.PL`, usually
|
|
|
|
`perl-devel` and `perl(ExtUtils::MakeMaker) >= 6.76` are the only
|
|
|
|
`BuildRequires` needed outside of the test suite.
|
|
|
|
|
|
|
|
Inside the module source, there will be a file usually called `META.json`
|
|
|
|
or `MYMETA.json` that can be used to find out the proper build
|
|
|
|
requirements.
|
|
|
|
|
|
|
|
There will be a JSON entry called `"prereqs"` that has the information
|
|
|
|
needed.
|
|
|
|
|
|
|
|
Within that entry, ignore what it is `"develop"` but generally anything
|
|
|
|
that is `"configure"` should be added as a RPM spec `BuildRequires:`
|
|
|
|
meta tag, wrapped of course in `perl()`. For example:
|
|
|
|
|
|
|
|
"prereqs" : {
|
|
|
|
"configure" : {
|
|
|
|
"requires" : {
|
|
|
|
"ExtUtils::MakeMaker" : "6.78"
|
|
|
|
},
|
|
|
|
"suggests" : {
|
|
|
|
"JSON::PP" : "2.27300"
|
|
|
|
}
|
|
|
|
},
|
|
|
|
[...]
|
|
|
|
},
|
|
|
|
|
|
|
|
That would translate to:
|
|
|
|
|
|
|
|
BuildRequires: perl(ExtUtils::MakeMaker) >= 6.78
|
|
|
|
BuildRequires: perl(JSON::PP) >= 2.27300
|
|
|
|
|
|
|
|
Note that in that example, `perl(JSON::PP) >= 2.27300` is not *strictly*
|
|
|
|
required to build it as it is only listed as `"suggests"` but with a
|
|
|
|
few exception, I do `BuildRequires:` the `"suggests"`.
|
|
|
|
|
|
|
|
Those are the `BuildRequires:` that *must* be present on the RPM build
|
2023-04-24 18:57:04 +08:00
|
|
|
system regardless of whether or not tests are run.
|
2023-04-24 18:07:12 +08:00
|
|
|
|
2023-04-25 09:13:32 +08:00
|
|
|
Some (but not all) binary Perl modules will need a `BuildRequires:`
|
|
|
|
added for a library dependency, e.g. for XML::Parser which links
|
|
|
|
against `libexpat.so`:
|
|
|
|
|
|
|
|
BuildRequires: expat-devel
|
|
|
|
|
2023-04-24 19:00:15 +08:00
|
|
|
### Conditional Test Requirements
|
|
|
|
|
2023-04-24 18:57:04 +08:00
|
|
|
To run tests, the RPM build system will usually need quite a few additional
|
|
|
|
Perl modules available---modules used by the test scripts themselves.
|
2023-04-24 18:07:12 +08:00
|
|
|
|
2023-04-24 18:57:04 +08:00
|
|
|
Those `BuildRequires:` meta tags should be wrapped inside a conditional:
|
2023-04-24 18:07:12 +08:00
|
|
|
|
2023-04-24 18:57:04 +08:00
|
|
|
%if 0%{?runtests:1} == 1
|
|
|
|
BuildRequires: perl(Foo::Bar) >= 3.14159
|
|
|
|
[...]
|
|
|
|
%endif
|
|
|
|
|
|
|
|
That way, the RPM build system only needs to install them if the `%{runtests}`
|
|
|
|
macro is defined so that circular dependencies where A requires B for tests,
|
|
|
|
B requires C for tests, and C requires A for tests can be worked around by
|
|
|
|
building them without running tests first.
|
|
|
|
|
|
|
|
Again in the `"prereqs"` entry of the JSON file, there will be a `"runtime"`
|
|
|
|
and a `"test"` entry. Everything in there (except for the specified minimum
|
|
|
|
version of `perl`) should be added within the `%{runtests}` conditional. For
|
|
|
|
example:
|
|
|
|
|
|
|
|
"prereqs" : {
|
|
|
|
[...]
|
|
|
|
"runtime" : {
|
|
|
|
"requires" : {
|
|
|
|
"Carp" : "0",
|
|
|
|
"Data::Section" : "0",
|
|
|
|
"File::Spec" : "0",
|
|
|
|
"IO::Dir" : "0",
|
|
|
|
"Module::Load" : "0",
|
|
|
|
"Text::Template" : "0",
|
|
|
|
"parent" : "0",
|
|
|
|
"perl" : "5.006",
|
|
|
|
"strict" : "0",
|
|
|
|
"utf8" : "0",
|
|
|
|
"warnings" : "0"
|
|
|
|
}
|
|
|
|
},
|
|
|
|
"test" : {
|
|
|
|
"recommends" : {
|
|
|
|
"CPAN::Meta" : "2.120900"
|
|
|
|
},
|
|
|
|
"requires" : {
|
|
|
|
"ExtUtils::MakeMaker" : "0",
|
|
|
|
"File::Spec" : "0",
|
|
|
|
"Test::More" : "0.96",
|
|
|
|
"Try::Tiny" : "0"
|
|
|
|
}
|
|
|
|
}
|
|
|
|
},
|
|
|
|
|
|
|
|
would translate to:
|
|
|
|
|
|
|
|
%if 0%{?runtests:1} == 1
|
|
|
|
BuildRequires: perl(Carp)
|
|
|
|
BuildRequires: perl(Data::Section)
|
|
|
|
BuildRequires: perl(File::Spec)
|
|
|
|
BuildRequires: perl(IO::Dir)
|
|
|
|
BuildRequires: perl(Module::Load)
|
|
|
|
BuildRequires: perl(Text::Template)
|
|
|
|
BuildRequires: perl(parent)
|
|
|
|
BuildRequires: perl(strict)
|
|
|
|
BuildRequires: perl(utf8)
|
|
|
|
BuildRequires: perl(warnings)
|
|
|
|
BuildRequires: perl(CPAN::Meta) >= 2.120900
|
|
|
|
BuildRequires: perl(Test::More) >= 0.96
|
|
|
|
BuildRequires: perl(Try::Tiny)
|
|
|
|
%endif
|
|
|
|
|
|
|
|
Note that I left out `"perl" : "5.006"`, `"ExtUtils::MakeMaker" : "0"`,
|
|
|
|
and the second `"File::Spec" : "0"`.
|
|
|
|
|
|
|
|
Requiring specific versions of Perl itself is problematic because of
|
|
|
|
`Epoch:` metadata tags that were necessary due to RPM evaluating version
|
2023-04-28 18:08:59 +08:00
|
|
|
strings as integers delimited by a `.` while Perl evaluated everything
|
2023-04-24 18:57:04 +08:00
|
|
|
after the dot as fractional.
|
|
|
|
|
|
|
|
There is already a `BuildRequires: perl(ExtUtils::MakeMaker)` that
|
|
|
|
precedes the `%{runtests}` conditional, so a second is not needed. And
|
|
|
|
obviously do not also need two `BuildRequires: perl(File::Spec)` tags.
|
|
|
|
|
|
|
|
|
2023-04-28 18:08:59 +08:00
|
|
|
Run-Time Requirements
|
|
|
|
---------------------
|
2023-04-25 09:13:32 +08:00
|
|
|
|
|
|
|
For the RPM spec file `Requires:` tags, RPM is actually pretty good at
|
|
|
|
figuring that out automatically *however* I always set it up manually
|
|
|
|
anyway.
|
|
|
|
|
|
|
|
Use the `"runtime"` section of the `"prereqs"` from the `META.json` or
|
|
|
|
`MYMETA.json` file. For example:
|
|
|
|
|
|
|
|
|
|
|
|
"prereqs" : {
|
|
|
|
[...]
|
|
|
|
"runtime" : {
|
|
|
|
"requires" : {
|
|
|
|
"Carp" : "0",
|
|
|
|
"Data::Section" : "0",
|
|
|
|
"File::Spec" : "0",
|
|
|
|
"IO::Dir" : "0",
|
|
|
|
"Module::Load" : "0",
|
|
|
|
"Text::Template" : "0",
|
|
|
|
"parent" : "0",
|
|
|
|
"perl" : "5.006",
|
|
|
|
"strict" : "0",
|
|
|
|
"utf8" : "0",
|
|
|
|
"warnings" : "0"
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
|
|
|
|
That translates to:
|
|
|
|
|
|
|
|
Requires: perl(Carp)
|
|
|
|
Requires: perl(Data::Section)
|
|
|
|
Requires: perl(File::Spec)
|
|
|
|
Requires: perl(IO::Dir)
|
|
|
|
Requires: perl(Module::Load)
|
|
|
|
Requires: perl(Text::Template)
|
|
|
|
Requires: perl(parent)
|
|
|
|
Requires: perl(strict)
|
|
|
|
Requires: perl(utf8)
|
|
|
|
Requires: perl(warnings)
|
|
|
|
|
|
|
|
Notice again I left out the explicit Perl version requirement. An RPM
|
|
|
|
package archive restricts the building of the module to a specific series
|
|
|
|
of Perl versions (e.g. 5.36.x) or on some distributions, an even more
|
|
|
|
specific of Perl.
|
|
|
|
|
|
|
|
For YJL, this is handled with the `%{perl5_API}` and `%{perl5_ABI}`
|
|
|
|
RPM macros, but they should be used in such a way that the package
|
|
|
|
still works when built for another distribution.
|
|
|
|
|
|
|
|
For `noarch` packages, use the following:
|
|
|
|
|
|
|
|
%if 0%{?perl5_API:1} == 1
|
|
|
|
Requires: %{perl5_API}
|
|
|
|
%endif
|
|
|
|
|
|
|
|
For binary packages, instead use the following:
|
|
|
|
|
|
|
|
%if 0%{?perl5_ABI:1} == 1
|
|
|
|
Requires: %{perl5_ABI}
|
|
|
|
%endif
|
|
|
|
|
|
|
|
In both cases, those `Requires:` are provided by the YJL build of Perl
|
|
|
|
(see [perl.spec](SPECS/perl.spec)).
|
|
|
|
|
|
|
|
By wrapping the `Requires:` in a conditional, the spec files will still
|
|
|
|
build installable packages on other GNU/Linux distributions as well.
|
|
|
|
|
|
|
|
|
|
|
|
The RPM Package Description
|
|
|
|
---------------------------
|
|
|
|
|
|
|
|
For the `%description` part of a CPAN Perl Module, when available I
|
|
|
|
just take the description offered on CPAN. Sometimes it does require
|
|
|
|
some redaction for the purpose of a an RPM package.
|
|
|
|
|
|
|
|
|
|
|
|
The RPM Spec File Build Preparation Section
|
|
|
|
-------------------------------------------
|
|
|
|
|
|
|
|
Generally this will just be the two lines:
|
|
|
|
|
|
|
|
%prep
|
|
|
|
%setup -n %{cpanname}-%{version}
|
|
|
|
|
|
|
|
In once case, the `Changes` file which I like to package with the
|
|
|
|
`%doc` macro had an execution bit set on it in the source package.
|
|
|
|
|
|
|
|
In that case, I fixed it within `%prep`:
|
|
|
|
|
|
|
|
%prep
|
|
|
|
%setup -n %{cpanname}-%{version}
|
2023-04-28 18:08:59 +08:00
|
|
|
%__chmod -x Changes
|
2023-04-25 09:13:32 +08:00
|
|
|
|
|
|
|
|
|
|
|
The RPM Spec File Build Section
|
|
|
|
-------------------------------
|
|
|
|
|
|
|
|
Most (but not all) Perl modules on CPAN build using a `Makefile.PL`
|
|
|
|
file to generate the Makefile.
|
|
|
|
|
|
|
|
There are other build systems. I will cross that bridge when I come
|
|
|
|
to them and describe them here, so they can be water under the bridge.
|
|
|
|
|
|
|
|
### Makefile.PL Build System
|
|
|
|
|
|
|
|
When a Perl module has a `Makefile.PL` the `%build` section should
|
|
|
|
*almost always* look like this:
|
|
|
|
|
|
|
|
%build
|
|
|
|
%__perl Makefile.PL INSTALLDIRS=vendor NO_PACKLIST=1 NO_PERLLOCAL=1 OPTIMIZE="$RPM_OPT_FLAGS"
|
|
|
|
make %{?_smp_mflags}
|
|
|
|
|
|
|
|
The `INSTALLDIRS=vendor` tells `Makefile.PL` that this is being packaged
|
|
|
|
for installation and should use the directories defined when `%__perl`
|
|
|
|
was built for distribution vendor-provided Perl modules.
|
|
|
|
|
|
|
|
The `NO_PACKLIST=1` tells the `Makefile.PL` not to create a packlist.
|
2023-04-28 18:08:59 +08:00
|
|
|
A packlist interferes with RPM package installation and the functionality
|
2023-04-25 09:13:32 +08:00
|
|
|
is provided by RPM itself.
|
|
|
|
|
|
|
|
The `NO_PERLLOCAL=1` tells the `Makefile.PL` that `perllocal.pod` should
|
|
|
|
not be updated. That is for packages installed through the CPAN utility
|
|
|
|
itself (or manually built on the system).
|
|
|
|
|
|
|
|
The `OPTIMIZE="$RPM_OPT_FLAGS"` is really only needed for binary Perl
|
|
|
|
modules but it does not hurt anything when used with `noarch` Perl
|
|
|
|
modules. It allows the optimization flags set by RPM to be used. This
|
|
|
|
is important for binary modules as it includes things like
|
|
|
|
`-D_FORTIFY_SOURCE=2` that help protect against things like buffer
|
|
|
|
overflows from being exploited.
|
|
|
|
|
|
|
|
With the `make` command, the `%{?_smp_mflags}` again is really only
|
|
|
|
needed for binary Perl modules but does not hurt anything with `noarch`
|
|
|
|
Perl modules. It just speeds up the build process on systems that have
|
|
|
|
more than one CPU core available for building.
|
|
|
|
|
|
|
|
|
|
|
|
The RPM Spec File Check Section
|
|
|
|
-------------------------------
|
|
|
|
|
|
|
|
In almost all cases, the `%check` section of the RPM spec file should
|
|
|
|
look like this:
|
|
|
|
|
|
|
|
%check
|
|
|
|
%if 0%{?runtests:1} == 1
|
|
|
|
make test > %{name}-make.test.log 2>&1
|
|
|
|
%else
|
|
|
|
echo "make test not run during package build." > %{name}-make.test.log
|
|
|
|
%endif
|
|
|
|
|
|
|
|
The `%if` block only runs the test if the RPM build system has defined
|
|
|
|
the `%{runtests}` macro.
|
|
|
|
|
|
|
|
The `%else` block indicates that tests were not run when that macro has
|
|
|
|
not been defined on the build system.
|
|
|
|
|
|
|
|
YJL policy is to log test results and package them with `%doc` just in
|
|
|
|
case the end user ever wants or needs to review them, so that is why
|
|
|
|
it is important to indicate tests were not run when they are not run.
|
|
|
|
|
|
|
|
On the production build server they will always be run but to package
|
|
|
|
the results of tests with `%doc` the results file needs to exist even
|
|
|
|
if the tests were not run.
|
|
|
|
|
|
|
|
In some cases, such as when an X11 server is needed to run the tests,
|
|
|
|
the above `%check` system may need modification.
|
|
|
|
|
|
|
|
|
|
|
|
The RPM Spec File Install Section
|
|
|
|
---------------------------------
|
|
|
|
|
|
|
|
Both `noarch` and binary Perl modules generally need the following
|
|
|
|
`%install` section:
|
|
|
|
|
|
|
|
%install
|
|
|
|
make install DESTDIR=%{buildroot}
|
|
|
|
|
|
|
|
Perl tends to install modules without the write bit set. for noarch
|
|
|
|
packages that is not a problem, but for binary Perl modules it interferes
|
|
|
|
with the ability for RPM to strip the binaries.
|
|
|
|
|
|
|
|
Binary Perl modules thus need the following addition:
|
|
|
|
|
|
|
|
%{_fixperms} %{buildroot}%{perl5_vendorarch}
|
|
|
|
|
|
|
|
That will set the write bit so that RPM stripping works.
|
|
|
|
|
|
|
|
|
|
|
|
The RPM Spec File Files Section
|
|
|
|
-------------------------------
|
|
|
|
|
|
|
|
The `%files` should always set the `%defattr`:
|
|
|
|
|
|
|
|
%files
|
|
|
|
%defattr(-,root,root,-)
|
|
|
|
|
|
|
|
The package should own all directories it installs inside of the
|
|
|
|
`%{perl5_vendorlib}` (for noarch) or `%{perl5_vendorlib}` (for binary)
|
|
|
|
directories, even if those directories are already owned by a module
|
|
|
|
that is dependency.
|
|
|
|
|
|
|
|
With a dependency, it is all possible the dependency is installed in
|
2023-04-28 18:08:59 +08:00
|
|
|
either `%perl5_corelib` or `%perl5_sitelib` for `noarch` dependencies,
|
|
|
|
or in `%perl5_corearch` or `%perl5_sitearch` for binary dependencies.
|
2023-04-25 09:13:32 +08:00
|
|
|
|
|
|
|
In those cases, the Perl module being packages would leave empty
|
|
|
|
directories behind when uninstalled if it does own all directories
|
|
|
|
inside of its module install directory.
|
|
|
|
|
|
|
|
Since Perl likes to install without the write bit, I like to manually
|
|
|
|
specify the attributes of installed files without the write bit.
|
|
|
|
|
|
|
|
Due to a bug in current versions of RPM (see (00-RPM-POST-INSTALL-BUG.md))
|
|
|
|
the attributes of binary modules should set manually anyway.
|
|
|
|
|
|
|
|
Honestly the RPM bug may not matter for binary Perl modules, they may
|
|
|
|
not need the execution bit set to work on GNU/Linux, I do not know.
|
|
|
|
|
|
|
|
Anyway what I do is manually set the the attributes for text files
|
|
|
|
inside the Perl module directory to `0444` and I manually set the
|
|
|
|
attributes for binary files inside the Perl module directory to
|
|
|
|
`0555`. Thus, the attributes match what they looked like after the
|
|
|
|
install but before `%{_fixperms}` and before the RPM scriptlets that
|
2023-04-28 18:08:59 +08:00
|
|
|
automatically run after `%install`.
|
2023-04-25 09:13:32 +08:00
|
|
|
|
|
|
|
Example:
|
|
|
|
|
|
|
|
%files
|
2023-04-25 14:37:30 +08:00
|
|
|
%defattr(-,root,root,-)
|
2023-04-25 09:13:32 +08:00
|
|
|
%dir %{perl5_vendorarch}/XML
|
|
|
|
%attr(0444,root,root) %{perl5_vendorarch}/XML/Parser.pm
|
|
|
|
%dir %{perl5_vendorarch}/XML/Parser
|
|
|
|
%dir %{perl5_vendorarch}/XML/Parser/Encodings
|
|
|
|
%attr(0444,root,root) %{perl5_vendorarch}/XML/Parser/Encodings/Japanese_Encodings.msg
|
|
|
|
%attr(0444,root,root) %{perl5_vendorarch}/XML/Parser/Encodings/README
|
|
|
|
%attr(0444,root,root) %{perl5_vendorarch}/XML/Parser/Encodings/*.enc
|
|
|
|
%attr(0444,root,root) %{perl5_vendorarch}/XML/Parser/Expat.pm
|
|
|
|
%attr(0444,root,root) %{perl5_vendorarch}/XML/Parser/LWPExternEnt.pl
|
|
|
|
%dir %{perl5_vendorarch}/XML/Parser/Style
|
|
|
|
%attr(0444,root,root) %{perl5_vendorarch}/XML/Parser/Style/*.pm
|
|
|
|
%dir %{perl5_vendorarch}/auto/XML
|
|
|
|
%dir %{perl5_vendorarch}/auto/XML/Parser
|
|
|
|
%dir %{perl5_vendorarch}/auto/XML/Parser/Expat
|
|
|
|
%attr(0555,root,root) %{perl5_vendorarch}/auto/XML/Parser/Expat/Expat.so
|
|
|
|
|
2023-04-25 14:37:30 +08:00
|
|
|
### Man Pages
|
2023-04-25 09:13:32 +08:00
|
|
|
|
2023-04-25 14:37:30 +08:00
|
|
|
For man pages, the standard `0644` permissions are fine:
|
|
|
|
|
|
|
|
%attr(0644,root,root) %{_mandir}/man3/*.3*
|
|
|
|
|
|
|
|
### Make test log
|
|
|
|
|
|
|
|
The output of `make test` should be packaged as documentation:
|
|
|
|
|
|
|
|
%doc %{name}-make.test.log
|
|
|
|
|
|
|
|
### Package Documentation
|
|
|
|
|
|
|
|
Any documentation file within the Perl module source that is potentially
|
|
|
|
useful to the end user should be packaged with the `%doc` macro.
|
|
|
|
|
|
|
|
This usually includes the `Changes` file, a `README` file, any license
|
|
|
|
files, and with some packages the `examples` directory.
|
|
|
|
|
|
|
|
|
|
|
|
RPM Packaging of the License File(s)
|
|
|
|
------------------------------------
|
|
|
|
|
|
|
|
Note that specification of `%license` is part of the `%files` section.
|
|
|
|
|
|
|
|
Every Perl module __MUST__ package the upstream-provided License file(s)
|
|
|
|
using both the `%license` macro *and* the `%doc` macro.
|
|
|
|
|
|
|
|
Furthermore, the packager __MUST__ ensure that the `License:` meta-tag
|
|
|
|
matches the upstream-provided License file(s).
|
|
|
|
|
|
|
|
Unfortunately, a small handful of Perl modules on CPAN do not include
|
|
|
|
the applicable license files.
|
|
|
|
|
|
|
|
It is probably illegal and certainly bad form for anyone other that the
|
|
|
|
upstream maintainer to add a license file to a package.
|
|
|
|
|
|
|
|
For YJL there is a workaround. YJL has a packaged called
|
2023-04-28 18:08:59 +08:00
|
|
|
`common-CPAN-licenses` that contains *most* of the various Open Source
|
2023-04-25 14:37:30 +08:00
|
|
|
licenses used in Perl modules on CPAN.
|
|
|
|
|
|
|
|
When a Perl module does not include the license text *and* the text
|
|
|
|
of the licenses specified by the package are included in that package,
|
2023-04-28 18:08:59 +08:00
|
|
|
add the following to the Run-Time `Requires:` RPM spec file meta tags:
|
2023-04-25 14:37:30 +08:00
|
|
|
|
|
|
|
%if 0%{?perl5_cpanlic:1} == 1
|
|
|
|
Requires: common-CPAN-licenses
|
|
|
|
%endif
|
|
|
|
|
|
|
|
Then in the spec file `%install` section, add something like the
|
|
|
|
following:
|
|
|
|
|
|
|
|
%if 0%{?perl5_cpanlic:1} == 1
|
|
|
|
cat > Perl5-Licenses.txt << "EOF"
|
|
|
|
This package specifies it uses the Perl 5 licenses but did not include
|
|
|
|
them in the package source.
|
|
|
|
|
|
|
|
They can be found in the following directory:
|
|
|
|
|
|
|
|
%{perl5_cpanlic}/Perl5/
|
|
|
|
|
|
|
|
EOF
|
|
|
|
%endif
|
|
|
|
|
|
|
|
Obviously if the package does not specify the Perl 5 license, then that
|
|
|
|
needs to be tailored to the license it does specify.
|
|
|
|
|
|
|
|
The created `Perl5-Licenses.txt` (or whatever if it is a different
|
|
|
|
specified license) can then be conditionally included in `%files`:
|
|
|
|
|
|
|
|
%if 0%{?perl5_cpanlic:1} == 1
|
|
|
|
%license Perl5-Licenses.txt
|
|
|
|
%doc Changes README samples Perl5-Licenses.txt
|
|
|
|
%else
|
|
|
|
%doc Changes README samples
|
|
|
|
%endif
|
|
|
|
%doc %{name}-make.test.log
|
|
|
|
|
|
|
|
|
2023-04-29 22:56:27 +08:00
|
|
|
Disabling Makefile.PL Prompts
|
|
|
|
-----------------------------
|
|
|
|
|
|
|
|
Sometimes a Makefile.PL script will want user interaction. To just
|
|
|
|
accept the defaults, add the line:
|
|
|
|
|
|
|
|
PERL_MM_USE_DEFAULT=1 \
|
|
|
|
|
|
|
|
directly above the `perl Makefile.PL` line.
|
|
|
|
|
|
|
|
See the `ExtUtils::MakeMaker` documentation for more information.
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-04-25 14:37:30 +08:00
|
|
|
End Notes
|
|
|
|
---------
|
|
|
|
|
|
|
|
These are general guidelines. There are conditions that are not covered
|
|
|
|
by these guidelines, and conditions that may require deviation from them.
|
2023-04-25 09:13:32 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2023-04-24 18:07:12 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|