Mailinglist Archive: opensuse-factory (520 mails)

< Previous Next >
[opensuse-factory] New rpm macros to test package versions in spec files

I've written a few rpm macros that will help to write more readable spec
files which will require less maintenance work.

Consider you have a patch that has to be applied only with gcc 7. You'd
propably do something like:

%if 0%{?suse_version} > 1320
%patch0 -p1

That makes sense only once you know suse_version is a number that somehow
relates to the distribution version, once you know >1320 means Tumbleweed
and once you know that Tumbleweed currently has gcc 7 (which only happens
during a timeframe). It works, it's useful, but it's not nice. This is
just an example but for other cases you'd probably have to mix it with
checks for 0%{?leap_version}, 0%{?sle_version} and maybe also

With the new macros I just submitted you can do:

%if %{pkg_version_at_least gcc 7}
%patch0 -p1

Which is actually what you want to do: apply your patch when the gcc version
is 7.0 or newer. I think this makes spec files more readable and require
less maintenance work when any distribution changes other package versions
(think Leap 15 changing to gcc 7 in that example above) since it allows you
not to think about what package versions a distribution has, but about the
package versions themselves.

Instead of package names, you can also use the macros using bracket
capabilities like:

%if %{pkg_version_at_least cmake(Qt5Core) 5.7}

And of course, in more complex expressions:

%if %{pkg_version_at_least gcc 6} && %{pkg_version_less_than gcc 7.1}

Note that the package/bracket capability name doesn't need to necessarily
appear in a BuildRequires statement, it's enough that it's installed in the
system where the spec file is being built, so it can also be an indirect
requirement. Of course, when I say "installed in the system" I mean in
the chroot system where obs builds packages. Also, the version comparison
is provided by rpm, so it works with all kind of version strings like
1.0alpha, 1.0rc2 and such things.

The full list of macros added and simple descriptions is:

%pkg_version_at_least : Arguments are a package/capability name and a
version number and returns true if package >= version
%pkg_version_at_most : package <= version
%pkg_version_equals : package == version
%pkg_version_greater_than : package > version
%pkg_version_less_than : package < version
%pkg_version_not_equals : package != version

Those are the high-level macros, but it's also possible to use the
low-level version of those macros (though I would recommend to use
the high-level macros whenever possible):

%rpm_vercmp : Accepts two versions as parameters and returns -1, 0, 1
if the first version is less than, equal or greater than the second version
respectively. If the first version number is the string ~~~, it just returns
the same string in order to propagate errors.

%pkg_version : Accepts a package or capability name as argument and returns
the version number of the installed package. If no package provides the
argument, it returns the string ~~~.

%pkg_version_cmp : Accepts a package or capability name as first argument
and a version number as second argument and returns -1, 0, 1 or ~~~ . The
number values have the same meaning as in %rpm_vercmp and the ~~~ string
is returned if the package or capability can't be found.

Also, if you check for a package that is not installed in the system,
the package build will fail with something like:

[ 24s] error: /home/abuild/rpmbuild/SOURCES/libid3tag.spec:88: bad %if

Btw, I have to say thanks to Dominique and Michael Schroeder who helped me
get started on writing those macros and helped improve them.

Btw2, The real case issue that initiated this was a problem I had with
libid3tag since I found out a patch had to be applied only in a Staging
project that tested gperf 3.1 while both Factory and the devel project
for libid3tag still used gperf 3.0 where applying the patch would
break the build.

So, any opinion/suggestion about these macros?


Antonio Larrosa
To unsubscribe, e-mail: opensuse-factory+unsubscribe@xxxxxxxxxxxx
To contact the owner, e-mail: opensuse-factory+owner@xxxxxxxxxxxx

< Previous Next >