With capital B and I, of course.
I wrote yesterday about maintainer mode use by ebuilds and why it’s a problem. Today I want to focus on a slightly related issue: conditional patching and autotools rebuild.
One very common use of maintainer mode is due to conditional patching: you can’t inherit autotools.eclass conditionally, so you leave it up to the autotools to decide whether to rebuild themselves or not.
This is bad not only for the problems I outlined for maintainer mode itself, but also because conditional patch, as well as conditional autotools rebuild, is something you should not do in an ebuild unless there is an extremely good reason to.
The first problem is quite obviously that you cannot send conditional patches upstream (see also my old article Best practices for portable patches). In Gentoo we should really prefer patches taken from upstream and/or that can be sent and accepted by upstream.
But it’s not limited to that: conditional patches gets applied only on particular conditions, this means that if you are bumping the package and those conditions don’t apply to you, then you won’t be seeing whether the patch applies or not. And if it’s an important fix for a particular architecture, and the patch cannot apply, then that architecture will have a broken package. If it’s a build-fix you can live with it a bit (although it will upset with reason the users of that arch), but if it’s a runtime fix then it’s a problem, because it might go months without being noticed.
And it’s not just during bump, but also when you add a new patch, it might not stack correctly against one of the conditional patches, and you wouldn’t be seeing the failure. So for instance to fix a build error on one setup you might break build on a different one.
In general, you want the patches to be unconditional, and you want to rebuild autotools at the minimal change. This even if the rebuild would be needed by a reduced set of users. The reason is that it’s better to waste a little more time for all the users rather than having a (big or small) subset of them being stuck entirely because of a conditional patch or rebuild.
Also, the sooner you can send a patch upstream, the sooner you won’t be needing it in the ebuild. If you prepare a conditional, raw and quick patch to fix a setup, you cannot send it as it is to upstream, so you’ll have to either spend more time to prepare also a refined good patch, or you’ll have to deal with that patch for a long time. Neither solution is a good one for your workflow.
So please, don’t make anything conditional, unless it’s really really needed.
IMHO, there is one good reason for conditional autotools: SPEED.autoreconf is extremely slow, especially on older single-core machines. If I can avoid autoreconf in the common case, I do so.For example: there is one ebuild I maintain in an overlay which builds correctly except for the tests. To link the test binaries properly, I need to patch configure.in and run eautoreconf. Now, almost nobody, except for the ebuild maintainer (me) and similar masochists, cares about the tests.So I patch and run eautoreconf conditionally on “use test”. For 99% of the users of the ebuild, this means I save 20 seconds of their life. I think I am doing a good thing.
No it’s not, because as I said, if you are doing conditional patching is not something upstream will accept, if you don’t send it upstream, you’re going to always have the same problem.The solution is to send the patch upstream. If it’s just test failing, restrict them until upstream fixes them. The same applies for other very uncommon corner cases, get upstream to fix them, you won’t be needing to rebuild autotools.But if there is a chance that 3 users out of 100 will be unable to install the package because you fucked up a conditional rebuild, then the 20 seconds you’re sparing the other users will be outweighted for sure.The ebuilds in tree should do the Right Thing, not “what it seems to be the best for my case”, as that means adding one hack over the other over the other over the other, which causes ebuilds to bitrot easily and so on.
Conditional patching does in no way mean that upstream will not accept it. They will not accept it if it breaks unconditioned. A patch, that is conditionally applied in Gentoo for reasons of saving time of our users, does NOT automatically mean it doesn’t work if it were unconditional. Often it does (and it SHOULD) regardless of the ebuild applying it conditionally, and that’s just fine for upstream. Upstreams don’t need a proof of thousands of distribution users having tested the patch works unconditionally. They need to see the patch, see it is good for all conditions thanks to their knowledge of the package they maintain upstream, and run with it – they are happy, our users are happy (with conditional applying), and time is saved.
Problem is, when you do conditional patching you usually try to save time for yourself rather than just the users, so y ou don’t consider the cases for which the patch is not applied at all.Looking at the actual results we have in the tree, sorry but I prefer wasting a bit more time during build for the users by forcing this in policy rather than seeing people abusing the “bent rule” of being able to conditionally patch.I’m just being pragmatic here.
That’s in expense of our users – something I can not agree with in any way. Users are important. We need to find other ways for forcing clean patches – ones that don’t involve punishing the users in the process.
Well, I’m also thinking of users. I sincerely would prefer all users to waste a bit more time than having a handful of users not being able to proceed with build at all.In the first case, you’re just having a suboptimal solution that needs to be improved, in the latter case you have a full blown error.But our discussion the other day made me think a lot on the issue, I have some ideas that just might be feasible, but I’ll have to make some tests before. I’ll post something as soon as I can assess that it is actually feasible.