https://fedoraproject.org/wiki/Changes/Perl_replace_MODULE_COMPAT_by_macro
This document represents a proposed Change. As part of the Changes process, proposals are publicly announced in order to receive community feedback. This proposal will only be implemented if approved by the Fedora Engineering Steering Committee.
== Summary ==
A ''perl(:MODULE_COMPAT_%(eval "<nowiki>`%{__perl} -V:version`</nowiki>"; echo $version))'' run-time dependency will be replaced with a new ''%perl_require_compat'' macro in all Perl spec files.
The macro will expand differently based on architecture specificity of the binary packages. That will significantly shrink an amount of Perl packages required to be rebuilt with each Perl upgrade.
== Owner == * Name: [[User:jplesnik| Jitka Plesnikova]] * Email: jplesnik@redhat.com
=== Completed items ===
=== Items in progress === * Add `%perl_require_compat` macro to ''perl-srpm-macros'' in F38 * Add `%perl_require_compat` macro to ''perl-srpm-macros'' in F37 * Add `%perl_require_compat` macro to ''perl-srpm-macros'' in F36 * Add `%perl_require_compat` macro to ''perl-srpm-macros'' in F35 * Add `%perl_require_compat` macro to ''perl-srpm-macros'' in RHEL 9 * Update [[Packaging:Perl | Fedora Packaging Guidelines for Perl]] * Replace ''perl(:MODULE_COMPAT_XXX)'' by `%perl_require_compat` run-time in all F38 spec files (3259)
== Detailed Description ==
The list of packages that need to be rebuilt with the new major version of Perl is determined according to the dependency on ''perl(:MODULE_COMPAT_XXX)'' now.
In Fedora, all Perl modules run-require the versioned ''perl(:MODULE_COMPAT_XXX)'' provided by ''perl-libs'' now.
However, only multi-arch packages need to have a dependency on the particular version of Perl it was built against, or on a newer version of Perl that provides backward compatibility with it. For those packages, we need to ensure that the packages will use the right version of ''libperl.so'' for the Perl used during the rebuild.
The noarch packages don't need to be rebuilt against each new major version of Perl, they only have to require non-versioned ''perl-libs'' which includes all directories used by all Perl modules.
The macro ''%perl_require_compat'' will evaluate the run-require based on ''%{_target_cpu}''. The macro will be defined in the rpm ''perl-srpm-macros'' and the definition is:
`%perl_require_compat %[ "%{_target_cpu}" == "noarch" ? "perl-libs" : "%{!?perl_version:perl-libs}%{?perl_version:perl(:MODULE_COMPAT_%{perl_version})}" ]`
The macro ''%perl_requires_compat'' will evaluate to the correct value. There is a known, yet harmless, imperfection: The macro will evaluate to ''perl(:MODULE_COMPAT_XXX)'' even in noarch subpackages of a multi-arch main package. In this case, I recommend to use `Requires: %perl_require_compat`. The purpose of the change is a matter of simplifying the rebuild, where it depends if the source package produces at least one multi-arch binary package. Not on whether it makes a noarch subpackage next to it. If you don't want to see this imperfection you could use directly `Requires: perl-libs`.
The macro will work for all supported Fedoras and EPEL 9.
For EPEL 8 and older, it won't work, because the [https://rpm-software-management.github.io/rpm/manual/macros.html Expression Expansion] is not implemented there. In these versions, ''perl(:MODULE_COMPAT_%(eval "<nowiki>`%{__perl} -V:version`</nowiki>"; echo $version))'' must be used.
== Benefit to Fedora ==
It will simplify the rebuild and reduce the number of packages which have to be rebuild from 3259 to approximately 600. It should currently be enough to rebuild only multi-arch packages and those that are part of the Perl itself (dual-life packages). Here we need to ensure that the packages will use the right ''libperl.so'' for the Perl used. The new syntax will also be shorter and clearer for packagers.
== Scope == * Proposal owners: ** Submit Fedora Packaging Guidelines for Perl update to Fedora Packaging Committee. ** Update and rebuild perl-srpm-macros source package. ** Add ''%perl_require_compat'' to ''perl-srpm-macros'' package in older Fedoras. ** Replace Requires for ''perl(:MODULE_COMPAT_XXX)'' with ''%perl_require_compat'' in all spec files.
* Other developers: Get familiar with new Fedora Packaging Guidelines for Perl.
* Release engineering: No action needed. [https://pagure.io/releng/issues #Releng issue number] <!-- REQUIRED FOR SYSTEM WIDE CHANGES -->
* Policies and guidelines: N/A (not needed for this Change) <!-- REQUIRED FOR SYSTEM WIDE CHANGES --> <!-- Do the packaging guidelines or other documents need to be updated for this feature? If so, does it need to happen before or after the implementation is done? If a FPC ticket exists, add a link here. Please submit a pull request with the proposed changes before submitting your Change proposal. -->
* Trademark approval: N/A (not needed for this Change)
* Alignment with Objectives:
== Upgrade/compatibility impact == N/A
== How To Test ==
All multi-arch packages which use the macro should run-require ''perl(:MODULE_COMPAT_%{perl_version})'' and the ''noarch'' packages should run-require ''perl-libs'' except the case listed in '''Detailed Description'''.
== User Experience == There should not be any remarkable change in user experience.
== Dependencies == This change will affect 3259 source packages and all binary noarch packages. The rebuild of affected packages will be done by mass rebuild of Fedora 38. There is no dependency on other Fedora changes.
== Contingency Plan ==
* Contingency mechanism: The change will be reverted. * Contingency deadline: Before Mass Rebuild. * Blocks release? No.
== Documentation ==
== Release Notes ==
On 10. 11. 22 21:23, Ben Cotton wrote:
The macro ''%perl_require_compat'' will evaluate the run-require based on ''%{_target_cpu}''. The macro will be defined in the rpm ''perl-srpm-macros'' and the definition is:
`%perl_require_compat %[ "%{_target_cpu}" == "noarch" ? "perl-libs" : "%{!?perl_version:perl-libs}%{?perl_version:perl(:MODULE_COMPAT_%{perl_version})}" ]`
Jitka, have you considered making this an RPM dependency generator instead? What are the reasons not to use it?
On 10. 11. 22 21:57, Miro Hrončok wrote:
On 10. 11. 22 21:23, Ben Cotton wrote:
The macro ''%perl_require_compat'' will evaluate the run-require based on ''%{_target_cpu}''. The macro will be defined in the rpm ''perl-srpm-macros'' and the definition is:
`%perl_require_compat %[ "%{_target_cpu}" == "noarch" ? "perl-libs" : "%{!?perl_version:perl-libs}%{?perl_version:perl(:MODULE_COMPAT_%{perl_version})}" ]`
Jitka, have you considered making this an RPM dependency generator instead? What are the reasons not to use it?
Something like this should work:
File: /usr/lib/rpm/fileattrs/perllib.attr
%__perllib_requires() %{lua: if macros['1']:match('.+%.so$') and macros.perl_version then print('perl(:MODULE_COMPAT_' .. macros.perl_version .. ')') else print('perl-libs') end } %__perllib_path ^(%{perl_vendorarch}|%{perl_vendorlib})/.+
(Untested.)
On 11. 11. 22 13:13, Miro Hrončok wrote:
Something like this should work:
File: /usr/lib/rpm/fileattrs/perllib.attr
%__perllib_requires() %{lua: if macros['1']:match('.+%.so$') and macros.perl_version then
The quotes around 1 are actually redundant here, I've realized after sending the email:
if macros[1]:match('.+%.so$') and macros.perl_version then
print('perl(:MODULE_COMPAT_' .. macros.perl_version .. ')') else print('perl-libs') end } %__perllib_path ^(%{perl_vendorarch}|%{perl_vendorlib})/.+
(Untested.)
Something like this should work:
File: /usr/lib/rpm/fileattrs/perllib.attr
%__perllib_requires() %{lua: if macros['1']:match('.+%.so$') and macros.perl_version then print('perl(:MODULE_COMPAT_' .. macros.perl_version .. ')') else print('perl-libs') end } %__perllib_path ^(%{perl_vendorarch}|%{perl_vendorlib})/.+
(Untested.)
Thanks for hint. I'll check if it works for my change. Jitka
On 11/11/22 14:10, Jitka Plesnikova wrote:
Something like this should work:
File: /usr/lib/rpm/fileattrs/perllib.attr
%__perllib_requires() %{lua: if macros['1']:match('.+%.so$') and macros.perl_version then print('perl(:MODULE_COMPAT_' .. macros.perl_version .. ')') else print('perl-libs') end } %__perllib_path ^(%{perl_vendorarch}|%{perl_vendorlib})/.+
(Untested.)
Thanks for hint. I'll check if it works for my change. Jitka
MODULE_COMPAT is used for 1) Perl Modules and also 2) for packages which use perl interpreter or libperl.so. For the second case, the RPM dependency generator above does not work. These packages may not contain the Perl directories.
For now, I prefer to use the change describe in the proposal. It works for all these cases.
Jitka
On 15. 11. 22 8:14, Jitka Plesnikova wrote:
On 11/11/22 14:10, Jitka Plesnikova wrote:
Something like this should work:
File: /usr/lib/rpm/fileattrs/perllib.attr
%__perllib_requires() %{lua: if macros['1']:match('.+%.so$') and macros.perl_version then print('perl(:MODULE_COMPAT_' .. macros.perl_version .. ')') else print('perl-libs') end } %__perllib_path ^(%{perl_vendorarch}|%{perl_vendorlib})/.+
(Untested.)
Thanks for hint. I'll check if it works for my change. Jitka
MODULE_COMPAT is used for 1) Perl Modules and also 2) for packages which use perl interpreter or libperl.so. For the second case, the RPM dependency generator above does not work. These packages may not contain the Perl directories.
For now, I prefer to use the change describe in the proposal. It works for all these cases.
Thanks for looking into it. I am not surprised that an RPM generator I written in an email does not work out of the box for all the packages. It can be enhanced. Do you have a specific example I can have a look at? Don't packages using libperl.so already require a pretty specific soname version?
Do you think that saying something like this is generally a bad idea?
""" Packages with Perl modules installed in %{perl_vendorlib} or %{perl_vendorarch} will automatically gain dependency on perl-libs for pure Perl modules or a dependency on perl(:MODULE_COMPAT_<perl_version>) for libraries with compiled code.
Packages that require the Perl interpreter or libperl.so but do not install modules to the aforementioned directories or explicitly link to libperl.so.<perl_version> need to handle the dependency manually. """
To me, this still sounds like a massive improvement over both the status quo and %perl_require_compat.
MODULE_COMPAT is used for 1) Perl Modules and also 2) for packages which use perl interpreter or libperl.so. For the second case, the RPM dependency generator above does not work. These packages may not contain the Perl directories.
For now, I prefer to use the change describe in the proposal. It works for all these cases.
Thanks for looking into it. I am not surprised that an RPM generator I written in an email does not work out of the box for all the packages. It can be enhanced. Do you have a specific example I can have a look at? Don't packages using libperl.so already require a pretty specific soname version?
Do you think that saying something like this is generally a bad idea?
""" Packages with Perl modules installed in %{perl_vendorlib} or %{perl_vendorarch} will automatically gain dependency on perl-libs for pure Perl modules or a dependency on perl(:MODULE_COMPAT_<perl_version>) for libraries with compiled code.
Packages that require the Perl interpreter or libperl.so but do not install modules to the aforementioned directories or explicitly link to libperl.so.<perl_version> need to handle the dependency manually. """
To me, this still sounds like a massive improvement over both the status quo and %perl_require_compat.
The dependency generator for this case should be following:
cat perlcompat.attr %__perlcompat_requires() %{lua: if macros[1]:match('.+%.so$') and macros.perl_version then print('perl(:MODULE_COMPAT_' .. macros.perl_version .. ')') else print('perl-libs') end } %__perlcompat_path ^(%{perl_vendorarch}|%{perl_vendorlib}|%{perl_privlib}|%{perl_archlib})/.+
Should be the file add to perl-generators or perl-srpm-macros?
The file attributes rules are applied on each file separately, if I understand it correctly. It means that perl-libs and MODULE_COMPAT will be added for Perl modules with compiled code, because there are not only *.so files.
Is it acceptable to have both dependencies for these packages?
The list of the packages which use MODULE_COMPAT and do not contain Perl directories are here [1].
[1] https://jplesnik.fedorapeople.org/perl-module-compat/only-compat-no-dirs
Jitka
On 30. 11. 22 17:40, Jitka Plesnikova wrote:
MODULE_COMPAT is used for 1) Perl Modules and also 2) for packages which use perl interpreter or libperl.so. For the second case, the RPM dependency generator above does not work. These packages may not contain the Perl directories.
For now, I prefer to use the change describe in the proposal. It works for all these cases.
Thanks for looking into it. I am not surprised that an RPM generator I written in an email does not work out of the box for all the packages. It can be enhanced. Do you have a specific example I can have a look at? Don't packages using libperl.so already require a pretty specific soname version?
Do you think that saying something like this is generally a bad idea?
""" Packages with Perl modules installed in %{perl_vendorlib} or %{perl_vendorarch} will automatically gain dependency on perl-libs for pure Perl modules or a dependency on perl(:MODULE_COMPAT_<perl_version>) for libraries with compiled code.
Packages that require the Perl interpreter or libperl.so but do not install modules to the aforementioned directories or explicitly link to libperl.so.<perl_version> need to handle the dependency manually. """
To me, this still sounds like a massive improvement over both the status quo and %perl_require_compat.
The dependency generator for this case should be following:
cat perlcompat.attr %__perlcompat_requires() %{lua: if macros[1]:match('.+%.so$') and macros.perl_version then print('perl(:MODULE_COMPAT_' .. macros.perl_version .. ')') else print('perl-libs') end } %__perlcompat_path ^(%{perl_vendorarch}|%{perl_vendorlib}|%{perl_privlib}|%{perl_archlib})/.+
Should be the file add to perl-generators or perl-srpm-macros?
I'd say perl-generators considering %{perl_vendorarch} etc. is not even defined in the default buildroot where perl-srpm-macros is intalled.
The file attributes rules are applied on each file separately, if I understand it correctly. It means that perl-libs and MODULE_COMPAT will be added for Perl modules with compiled code, because there are not only *.so files.
Correct. In theory, a global Lua table can be used to cache the results based on %{name} and refuse to generate perl-libs dependency if the perl(:MODULE_COMPAT_...) one was already generated but I don't think it would work when the files appear in an unfortunate order. Also, probably not worth-it.
Is it acceptable to have both dependencies for these packages?
I don't see why not, they will both evaluate to the same package, so it should not matter.
The list of the packages which use MODULE_COMPAT and do not contain Perl directories are here [1].
[1] https://jplesnik.fedorapeople.org/perl-module-compat/only-compat-no-dirs
Thanks, I will have a look.
On 30. 11. 22 19:07, Miro Hrončok wrote:
The list of the packages which use MODULE_COMPAT and do not contain Perl directories are here [1].
[1] https://jplesnik.fedorapeople.org/perl-module-compat/only-compat-no-dirs
Thanks, I will have a look.
noarch packages would only require perl-libs instead of perl(:MODULE_COMPAT...) with %perl_require_compat. I've checked all noarch packages from the list: they already require /usr/bin/perl (which requires perl-libs and perl(:MODULE_COMPAT...)).
The only exception is EekBoek which already requires perl-interpreter manually anyway (it also requires perl-generators which I don't understand).
The arched packages from the list are a bit more complex than that.
Some of them require libperl.so.5.36()(64bit) which is probably good enough.
Some of them don't require perl(:MODULE_COMPAT_5.36.0) or anything perl-ish based on my query (e.g. asterisk, claws-mail or zypper) -- maybe I need to query a specific subpackge instead?
Some fo them require /usr/bin/perl and I think would not need to require perl(:MODULE_COMPAT_5.36.0) even when not noarch. My (unverified) assumption is that the packages contains compiled executables, but no Perl modules. They probably only contain Perl script (e.g. docbook2X, emacspeak or freeradius).
On Thu, Nov 10, 2022 at 8:24 PM Ben Cotton bcotton@redhat.com wrote:
=== Items in progress ===
- Add `%perl_require_compat` macro to ''perl-srpm-macros'' in F38
- Add `%perl_require_compat` macro to ''perl-srpm-macros'' in F37
- Add `%perl_require_compat` macro to ''perl-srpm-macros'' in F36
- Add `%perl_require_compat` macro to ''perl-srpm-macros'' in F35
- Add `%perl_require_compat` macro to ''perl-srpm-macros'' in RHEL 9
- Update [[Packaging:Perl | Fedora Packaging Guidelines for Perl]]
- Replace ''perl(:MODULE_COMPAT_XXX)'' by `%perl_require_compat`
run-time in all F38 spec files (3259)
For those of us that prefer linear (and release agnostic) spec files, could the %perl_require_compat macro for el7, and el8, simply map to the classic MODULE_COMPAT... syntax without the need for expression expansion (no improvement, but no regression, either)?