On Wed, May 31, 2017 at 6:23 AM, Antonio Larrosa <alarrosa@suse.de> wrote:
Hi,
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 %endif
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 0%{?is_opensuse}.
With the new macros I just submitted you can do:
%if %{pkg_version_at_least gcc 7} %patch0 -p1 %endif
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 condition
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?
Greetings,
Not that I don't appreciate the technical ingenuity that is involved in making these kinds of macros, but this feels like miles of bad road. It makes it really easy for people to do dumb patches and then just let them build up. And among other things, conditional patch application makes for builds with more "surprises" in them. I also feel like this just makes it easier to not try to properly fix things. In my experience, most of the time, a proper fix for things like compiler/Qt issues typically don't break older compilers or Qt versions. In general, I think we should be doing *way less* conditional patching, not more. Then again, I'm not sure how much "working with upstream projects" is promoted in openSUSE compared to Fedora (where most of my packaging experience comes from). -- 真実はいつも一つ!/ Always, there's only one truth! -- To unsubscribe, e-mail: opensuse-factory+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-factory+owner@opensuse.org