Dear all,
TL;DR: how do packages like pyproject-srpm-macros and the like end up in the default buildroot of different versions of Fedora (official, therefore Koji), EPEL, but also Copr chroots? Is there any documentation about this or could somebody guide me in this process? I've seen that they are required in redhat-rpm-config, so it's fair to assume that one should open a PR there to begin with. But then I have seen that e.g. Copr has different versions of this package compared to e.g. Koji, right?
Longer explanation: I would like to submit a self-contained change to bring R macros to the 21st century, make use of dynamic buildrequires for R packages and so on, so that the R packaging experience is on par with other languages. I'm planning an %R_meta macro, similar to %gometa, but for this to work, as you know, the default buildroot must have it in the first place via some R-srpm-macros (which currently does not exist). I did not find any piece of documentation describing such a procedure, but virtually all the other languages have their <you_name_it>-srpm-macros added there, so I assume there are a number of people here that may help me navigate this.
Thanks in advance,
On 16. 10. 25 20:41, Iñaki Ucar wrote:
Dear all,
TL;DR: how do packages like pyproject-srpm-macros and the like end up in the default buildroot of different versions of Fedora (official, therefore Koji),
By being Required by redhat-rpm-config which itself is pulled in by being in the @build and @buildsystem-build comps groups.
One of them is defined in Koji, the other is in https://pagure.io/fedora-comps/blob/main/f/comps-f44.xml.in#_393
EPEL, but also Copr chroots?
For EPEL it's either Required by redhat-rpm-config from RHEl or by epel-rpm-macros. FOr Copr chroots, it's again the same, the groups are defined in chroot_setup_cmd e.g. in https://github.com/rpm-software-management/mock/blob/main/mock-core-configs/...
Is there any documentation about this or could somebody guide me in this process?
I have a TODO item to write packaging guidelines for this but I never have time to do it :(
I've seen that they are required in redhat- rpm-config, so it's fair to assume that one should open a PR there to begin with.
Correct.
But then I have seen that e.g. Copr has different versions of this package compared to e.g. Koji, right?
It might have a tad older one, as it uses the mirrored repos by default, but eventually it will reach Copr as well.
Longer explanation: I would like to submit a self-contained change to bring R macros to the 21st century, make use of dynamic buildrequires for R packages and so on, so that the R packaging experience is on par with other languages. I'm planning an %R_meta macro, similar to %gometa, but for this to work, as you know, the default buildroot must have it in the first place via some R-srpm- macros (which currently does not exist). I did not find any piece of documentation describing such a procedure, but virtually all the other languages have their <you_name_it>-srpm-macros added there, so I assume there are a number of people here that may help me navigate this.
I am not great fan of the %...meta approach, but yes, I can help you review the plan.
On Thu, 16 Oct 2025 at 20:58, Miro Hrončok mhroncok@redhat.com wrote:
<snip>
I am not great fan of the %...meta approach, but yes, I can help you review the plan.
Thank you, much appreciated. [1] is the current status of my plan. So the most immediate question now is how to test this. I naively tried to rebuild a new version of redhat-rpm-config in Copr with the new Requires, but it didn't work. So I suppose the question is how do I set up a test buildroot with this development version.
[1] https://github.com/rpm-software-management/R-rpm-macros/pull/2#issuecomment-...
On 16. 10. 25 21:11, Iñaki Ucar wrote:
I naively tried to rebuild a new version of redhat-rpm-config in Copr with the new Requires, but it didn't work.
That's because Copr builds SRPMs in a different chroot. I am afraid you can only test this locally.
On Thu, 16 Oct 2025 at 21:41, Miro Hrončok mhroncok@redhat.com wrote:
On 16. 10. 25 21:11, Iñaki Ucar wrote:
I naively tried to rebuild a new version of redhat-rpm-config in Copr
with the
new Requires, but it didn't work.
That's because Copr builds SRPMs in a different chroot. I am afraid you can only test this locally.
I see. And do you know whether mock's --additional-package flag is suitable for this? Or do I need to build an actual image and supply it via --buildroot-image?
On 17. 10. 25 10:08, Iñaki Ucar wrote:
On Thu, 16 Oct 2025 at 21:41, Miro Hrončok <mhroncok@redhat.com mailto:mhroncok@redhat.com> wrote:
On 16. 10. 25 21:11, Iñaki Ucar wrote: > I naively tried to rebuild a new version of redhat-rpm-config in Copr with the > new Requires, but it didn't work. That's because Copr builds SRPMs in a different chroot. I am afraid you can only test this locally.I see. And do you know whether mock's --additional-package flag is suitable for this? Or do I need to build an actual image and supply it via --buildroot-image?
I don't think you need to deal with the image at all.
--additional-package might work but what you really work is to point your mock config to your copr (or other) repository and then use mock to 1) build SRPM 2) build the RPM.
See e.g. https://copr.fedorainfracloud.org/coprs/g/python/python3.15/ for how to create a custom mock config.
Then:
mock -r your_config --resultdir=./ --buildsrpm --spec xxx.spec --source xxx-1.0.0.tar.gz mock -r your_config xxx...src.rpm
On Fri, 17 Oct 2025 at 10:58, Miro Hrončok mhroncok@redhat.com wrote:
On 17. 10. 25 10:08, Iñaki Ucar wrote:
On Thu, 16 Oct 2025 at 21:41, Miro Hrončok <mhroncok@redhat.com mailto:mhroncok@redhat.com> wrote:
On 16. 10. 25 21:11, Iñaki Ucar wrote: > I naively tried to rebuild a new version of redhat-rpm-config inCopr
with the > new Requires, but it didn't work. That's because Copr builds SRPMs in a different chroot. I am afraidyou can
only test this locally.I see. And do you know whether mock's --additional-package flag is
suitable for
this? Or do I need to build an actual image and supply it via
--buildroot-image?
I don't think you need to deal with the image at all.
--additional-package might work but what you really work is to point your mock config to your copr (or other) repository and then use mock to 1) build SRPM 2) build the RPM.
See e.g. https://copr.fedorainfracloud.org/coprs/g/python/python3.15/ for how to create a custom mock config.
Works like a charm, thanks.
One more question. Is it possible to check if BuildArch: noarch has been set? I tried checking %{buildarch} with no luck.
Iñaki
On Fri, 17 Oct 2025 at 13:12, Iñaki Ucar iucar@fedoraproject.org wrote:
On Fri, 17 Oct 2025 at 10:58, Miro Hrončok mhroncok@redhat.com wrote:
On 17. 10. 25 10:08, Iñaki Ucar wrote:
On Thu, 16 Oct 2025 at 21:41, Miro Hrončok <mhroncok@redhat.com mailto:mhroncok@redhat.com> wrote:
On 16. 10. 25 21:11, Iñaki Ucar wrote: > I naively tried to rebuild a new version of redhat-rpm-config inCopr
with the > new Requires, but it didn't work. That's because Copr builds SRPMs in a different chroot. I am afraidyou can
only test this locally.I see. And do you know whether mock's --additional-package flag is
suitable for
this? Or do I need to build an actual image and supply it via
--buildroot-image?
I don't think you need to deal with the image at all.
--additional-package might work but what you really work is to point your mock config to your copr (or other) repository and then use mock to 1) build SRPM 2) build the RPM.
See e.g. https://copr.fedorainfracloud.org/coprs/g/python/python3.15/ for how to create a custom mock config.
Works like a charm, thanks.
-- Iñaki Úcar
On Fri, Oct 17, 2025 at 5:15 AM Iñaki Ucar iucar@fedoraproject.org wrote:
One more question. Is it possible to check if BuildArch: noarch has been set? I tried checking %{buildarch} with no luck.
Check whether %{_target_cpu} has the value "noarch".
On Fri, 17 Oct 2025 at 16:26, Jerry James loganjerry@gmail.com wrote:
On Fri, Oct 17, 2025 at 5:15 AM Iñaki Ucar iucar@fedoraproject.org wrote:
One more question. Is it possible to check if BuildArch: noarch has been
set? I tried checking %{buildarch} with no luck.
Check whether %{_target_cpu} has the value "noarch".
Oh, that's a good one, many thanks!
On 10/16/25 1:41 PM, Iñaki Ucar wrote:
TL;DR: how do packages like pyproject-srpm-macros and the like end up in the default buildroot of different versions of Fedora (official, therefore Koji), EPEL, but also Copr chroots? Is there any documentation about this or could somebody guide me in this process?
Hi,
The correct way to add an SRPM macros package to the default buildroot is to add Requires to redhat-rpm-config. redhat-rpm-config is installed by default in the Fedora mock chroot, on both Koji and Copr and mock on your local system and pulled in by the Fedora packaging stack and available for use locally with fedpkg srpm. If you have macros that are packaged in EPEL and need to be in the default EPEL buildroot, you can also add Requires to the epel-rpm-macros package.
I'm planning an %R_meta macro, similar to %gometa, but for this to work, as you know, the default buildroot must have it in the first place via some R-srpm-macros (which currently does not exist).
I would suggest you consider refactoring your macros so they don't need to be installed at SRPM parse time. After taking over maintenance of the forge and go macros which use the %foometa approach that dynamically sets a bunch of global macros in lua which the packager then uses to fill out the specfile preamble, I am starting to realize that this approach is more trouble than it's worth.
Best, Maxwell
On Thu, 16 Oct 2025 at 21:06, Maxwell G maxwell@gtmx.me wrote:
<snip>
I'm planning an %R_meta macro, similar to %gometa, but for this to
work, as you know, the default buildroot must have it in the first place via some R-srpm-macros (which currently does not exist).
I would suggest you consider refactoring your macros so they don't need to be installed at SRPM parse time. After taking over maintenance of the forge and go macros which use the %foometa approach that dynamically sets a bunch of global macros in lua which the packager then uses to fill out the specfile preamble, I am starting to realize that this approach is more trouble than it's worth.
Ok, valuable advice. My current approach is in [1]. I liked the idea of automating a bunch of things, so I wrote [2]. But feedback is very welcome, and particularly what would you do instead of this given your experience.
[1] https://github.com/rpm-software-management/R-rpm-macros/pull/2#issuecomment-...
[2] https://github.com/rpm-software-management/R-rpm-macros/blob/8d2386f40cc6a25...
On 10/16/25 2:15 PM, Iñaki Ucar wrote:
Ok, valuable advice. My current approach is in [1]. I liked the idea of automating a bunch of things, so I wrote [2]. But feedback is very welcome, and particularly what would you do instead of this given your experience.
Sure! You may also be interested in [1] which is a cheatsheet to writing macros. I'll go through each part of the sample spec you posted:
%global R_repo cran # repository: cran (default), bioc
I would avoid requiring packagers to set global variables. See in "Avoid control macros" in the page I linked. Hopefully, you can factor this out if you remove %R_meta.
%global R_name example # package name
Same as above.
%global R_vers 1.2-3 # version in upstream format
Is this necessary? Can't you just set Version to a static value?
%global R_comp 1 # needs compilation? 0 (default), 1
I would just remove this and require packagers to manually set BuildArch: noarch if appropriate.
%R_meta # BR R-devel + noarch if needed + compute variables below
Having a macro add a BuildRequires line to the spec preamble is a bit magical, and it's only one line that packagers who have to include.
Alternatively, you could create a stub %R_buildrequires that only echoes R-devel and exits. Then mock will install R-devel which will pull in the package that includes the fully implemented %R_buildrequires macro and then mock will re-run %generate_buildrequires, go and install the rest of the Buildrequires printed by the real %R_buildrequires and then continue building the package. You can see pyproject-rpm-macros and pyproject-srpm-macros for an example. Personally, I don't particularly like this approach. It's a lot of complication and it only saves one manual BuildRequires line in the specfile.
As for the other macros that it calculates and defines, I would just define those macros directly in macros.R-srpm instead of using an intermediate macro to set them with rpm.define within the specfile.
Name: %{R_name_rpm}
The Go macros used to dynamically calculate Name and then the Packaging Committee asked us to stop. It was a big headache when we needed to make changes to the name calculation lua code without breaking existing packages. Also, this can cause various problems when an SRPM is built on a system that does not have the available macro implementation (or an old, broken version) that's used to generate Name.
Version: %{R_vers_rpm}
See above.
URL: %{R_url}
Instead of having a macro to define another macro used later in the specfile (%R_meta defines R_url), you could define a simple parametric RPM macro named R_url in macros.R-srpm that takes the name of the project as an argument (or less ideally, reads the variables set earlier in the spec). See [2] for an example.
Source: %{R_source}
I have the same suggestion as I did for R_url. Statically define a R_source macro in macros.R-srpm instead of using %R_meta. You can see %pypi_source in python-srpm-macros as an example.
[1] https://gtmx.me/Wiki/Fedora/developing_rpm_macros/ [2] https://src.fedoraproject.org/rpms/ansible-packaging/blob/rawhide/f/macros.a...
Thanks for all the feedback! Comments inline:
On Thu, 16 Oct 2025 at 22:12, Maxwell G maxwell@gtmx.me wrote:
On 10/16/25 2:15 PM, Iñaki Ucar wrote:
Ok, valuable advice. My current approach is in [1]. I liked the idea of automating a bunch of things, so I wrote [2]. But feedback is very welcome, and particularly what would you do instead of this given your experience.
Sure! You may also be interested in [1] which is a cheatsheet to writing macros.
This is very useful, thank you.
I'll go through each part of the sample spec you posted:
%global R_repo cran # repository: cran (default), bioc
I would avoid requiring packagers to set global variables. See in "Avoid control macros" in the page I linked. Hopefully, you can factor this out if you remove %R_meta.
The thing is that we already have to set several global variables. I'm trying here at least to have some benefit out of it via automation.
About this in particular, there are two standard repositories, and the goal would be to automate the URL and Source fields. Of course, I could also generate a %cran_url, %cran_source, %bioc_url, and %bioc_source macros instead. But then again, I would still need to put them in the default buildroot, right? You said "I would suggest you consider refactoring your macros so they don't need to be installed at SRPM parse time", and I agree this would be perfect, but then, many cumbersome things happens with the URL's, name, version and library placement (more of this below), so, correct me if I'm wrong, but any kind of automation here needs to be installed at SRPM parse time, right?
%global R_name example # package name
Same as above.
The upstream package name is used in many places, and it's different from the rpm name, so basically all specs are currently setting a global variable for this.
%global R_vers 1.2-3 # version in upstream format
Is this necessary? Can't you just set Version to a static value?
Sometimes, when the upstream version is compatible with our versioning system. But many times it's not, like the one in the example, that has a "-". In those cases, the upstream version is used in several places, and the rpm version in some others. So packages are already defining one (sometimes several) global variables for this. Or they have to update the version in several places, which is prone to errors.
%global R_comp 1 # needs compilation? 0 (default), 1
I would just remove this and require packagers to manually set BuildArch: noarch if appropriate.
The thing is that it's not only the BuildArch. Packages go into different directories depending on this. Currently, packages have to set
%global rlibdir %{_libdir}/R/library
for packages that require compilation, and
%global rlibdir %{_datadir}/R/library
+ BuildArch: noarch for packages that don't. This global is more obscure in my opinion. So I'd like to automate it. Can I check with a macro if BuildArch: noarch was set?
%R_meta # BR R-devel + noarch if needed + compute
variables below
Having a macro add a BuildRequires line to the spec preamble is a bit magical, and it's only one line that packagers who have to include.
Alternatively, you could create a stub %R_buildrequires that only echoes R-devel and exits. Then mock will install R-devel which will pull in the package that includes the fully implemented %R_buildrequires macro and then mock will re-run %generate_buildrequires, go and install the rest of the Buildrequires printed by the real %R_buildrequires and then continue building the package. You can see pyproject-rpm-macros and pyproject-srpm-macros for an example. Personally, I don't particularly like this approach. It's a lot of complication and it only saves one manual BuildRequires line in the specfile.
As for the other macros that it calculates and defines, I would just define those macros directly in macros.R-srpm instead of using an intermediate macro to set them with rpm.define within the specfile.
So basically you don't recommend the automagic of such a macro, right? But as discussed above, the main problem still persists: SRPM macros need to be required in the default buildroot. So my line of thought was: given that I have to do this anyway, why not improve everyone else's life? :)
Name: %{R_name_rpm}
The Go macros used to dynamically calculate Name and then the Packaging Committee asked us to stop. It was a big headache when we needed to make changes to the name calculation lua code without breaking existing packages. Also, this can cause various problems when an SRPM is built on a system that does not have the available macro implementation (or an old, broken version) that's used to generate Name.
I'd really really really like to automate 3 things:
- Version normalization, so that the packager defines just the upstream version in the header, as a global variable, and then some macro takes care of setting the proper rpm version, etc.
- Setting the rlibdir appropriately (see above two comments ago).
- Setting URLs and Sources automatically.
I agree that setting this automagic name vs manually setting R-%{R_name} is not much of a difference. But I thought that, given the automations above, it would be better to set this one too for consistency. Here the name calculation is pretty straightforward and it's not expected to change.
Version: %{R_vers_rpm}
See above.
URL: %{R_url}
Instead of having a macro to define another macro used later in the specfile (%R_meta defines R_url), you could define a simple parametric RPM macro named R_url in macros.R-srpm that takes the name of the project as an argument (or less ideally, reads the variables set earlier in the spec). See [2] for an example.
Source: %{R_source}
I have the same suggestion as I did for R_url. Statically define a R_source macro in macros.R-srpm instead of using %R_meta. You can see %pypi_source in python-srpm-macros as an example.
[1] https://gtmx.me/Wiki/Fedora/developing_rpm_macros/ [2]
https://src.fedoraproject.org/rpms/ansible-packaging/blob/rawhide/f/macros.a...
I'll take a look, thanks.
Best,
Hi,
On 10/17/25 3:38 AM, Iñaki Ucar wrote:
About this in particular, there are two standard repositories, and the goal would be to automate the URL and Source fields. Of course, I could also generate a %cran_url, %cran_source, %bioc_url, and %bioc_source macros instead. But then again, I would still need to put them in the default buildroot, right? You said "I would suggest you consider refactoring your macros so they don't need to be installed at SRPM parse time", and I agree this would be perfect, but then, many cumbersome things happens with the URL's, name, version and library placement (more of this below), so, correct me if I'm wrong, but any kind of automation here needs to be installed at SRPM parse time, right?
Yes, macros that need to set fields in spec preamble have to be available at SRPM parse time. If you want to automate these things, then it's fine to have those macros in the default buildroot. My main concern is the complicated `%foometa` approach, and I'd also suggest keeping the Name and Version fields static. Generating URLs and Sources by using statically defined macros in macros.R-srpm definitely makes sense to me and does save packager time by avoiding the need to copy complex package regsitry download URLs.
> %global R_name example # package name Same as above.The upstream package name is used in many places, and it's different from the rpm name, so basically all specs are currently setting a global variable for this.
I would caution against dynamically computing the Name: field. Having Names that can unexpectedly change when the macro code changes seems too risky for not a lot of benefit.
> %global R_vers 1.2-3 # version in upstream format Is this necessary? Can't you just set Version to a static value?Sometimes, when the upstream version is compatible with our versioning system. But many times it's not, like the one in the example, that has a "-". In those cases, the upstream version is used in several places, and the rpm version in some others. So packages are already defining one (sometimes several) global variables for this. Or they have to update the version in several places, which is prone to errors.
Dynamic Version can cause issues with other tools, especially if it involves executing lua to determine it. If you really want to automate Version, would it be possible to do it the other way around: set Version: statically in the specfile and then define R_vers in macros.R-srpm (using lua if necessary) based on the standard heuristic to convert an RPM version to an upstream version? If needed, packagers could still override R_vers manually in the specfile.
> %global R_comp 1 # needs compilation? 0 (default), 1 I would just remove this and require packagers to manually set BuildArch: noarch if appropriate.The thing is that it's not only the BuildArch. Packages go into different directories depending on this.
What part of the specfile needs to know this? If it's just `%R_save_files` or the other macros that expand to shell code / calls to external programs in the RPM %build/%install scripts once the sources are already unpacked, is there upstream metadata in the sources that the code could reliably read and then determine which directory to use instead of requiring packagers to set a macro or trying to read the value of BuildArch? That would be more robust and prevent packager mistakes.
Best, Maxwell