2

I want to create a cross-distribution RPM spec file for an application that bundles a certain library. The application uses this bundled library by default, but also provides a build-time option for using the version of the library installed in the system instead. I want the RPM to link the application to the system library if it is available (since this will make the package smaller, and because the system library gets security patches more frequently than the version bundled with the application) and if not, to fall back to the (default) bundled version. Is there any way of writing a conditional in the spec file that accomplishes this?

For example, I want to do something like

%if available(libfoo-devel >= 1.0)
BuildRequires: libfoo-devel >= 1.0
%endif
 
%prep
cat << EOF > build_config_file
%if available(libfoo-devel >= 1.0)
ac_add_options --with-system-foo
%endif
EOF

Right now I'm using conditionals that check for macros defined by particular versions of OSes that I already know package the correct library, but this is rather brittle and convoluted. (That is, I need to manually check each target distribution to see if it packages the correct version of the library, and then write a condition in the spec file for that distribution; moreover, I need to repeat this process periodically in case the correct version of the library becomes available for a distribution that didn't package it previously.) It would be simpler if I could just test for the availability of the dependency directly.

Psychonaut
  • 859
  • 8
  • 22

1 Answers1

1

You must decide before creating the rpm how you will create it. Compilation happens before the target rpm is created, not upon installation.

As I see it you might consider creating two rpms:

  • one compiled with libfoo-devel
  • one without

I would then suggest a spec file along these lines:

Name: package
...

%package libfoo
Summary:  %{name} build with libfoo
BuildRequires: libfoo-devel >= 1.0
Requires: libfoo >= 1.0

%build
build --without-libfoo --target "${RPM_BUILD_ROOT}/usr/bin/without-libfoo"
build --with-libfoo --target "${RPM_BUILD_ROOT}/usr/bin/with-libfoo"

%install
/usr/bin/without-libfoo

%install libfoo
/usr/bin/with-libfoo

Notes:

  • yes this means compiling twice: once with and once without libfoo
  • building this spec file will create two packages: "package.rpm" and "package-libfoo.rpm"
Chris Maes
  • 35,025
  • 12
  • 111
  • 136
  • I'm not clear on how this answer addresses the question. With this setup, won't attempting to build the RPM fail on systems that don't provide libfoo-devel? – Psychonaut May 05 '21 at 13:15
  • Yes indeed, but I think you are confused about the difference between "build-machines" and "machines where the rpm is to be installed". Your spec file should not adapt to the build-machine, but you can create different rpms to target different kinds of machines where the packages are to be installed. – Chris Maes May 05 '21 at 13:48
  • I'm trying to write a single [cross-distribution spec file](https://en.opensuse.org/openSUSE:Build_Service_cross_distribution_howto) that an [OBS](https://openbuildservice.org/) instance can use to conditionally generate RPMs for various GNU/Linux distros (or different versions of the same distro). It's entirely expected for such spec files to account for different build environments. The whole point of this is to avoid maintaining separate but nearly identical spec files (and associated build service projects) per distribution. – Psychonaut May 05 '21 at 14:12
  • Allright, but I think you should change your requirement: not "if libfoo-devel is on the system", but rather "if I'm on centos>=7 then BuildRequires libfoo-devel". You should define beforehand whether you want to build with libfoo-devel, not based on whether it is present on the system which would result in random build results. – Chris Maes May 05 '21 at 14:20
  • This is what I'm doing right now, but the disadvantage is that I need to manually check whether libfoo-devel > 1.0 exists for each distribution I want to build for and then hard-code this distribution information into a condition in the spec file. And I need to periodically repeat this process in case libfoo-devel > 1.0 becomes available for distros that didn't have it before. – Psychonaut May 05 '21 at 14:25