Optional runtime dependencies (or «suggested dependencies») are one of the late problems we’re facing in Gentoo. There’s definitely a need for some standard solution, and it’d be great to put it in the next EAPI. Sadly, there’s no consensus how to solve it.
The optional dependencies problem
Gentoo has a very neat solution for handling optional dependencies and optional features, probably ever since the beginning. It is called «USE flags» and they work very well with the «traditional» optional dependencies. By that, I mean optional dependencies which are both build- and run-time.
Such a dependencies have to be pulled in before the build process starts, and usually require passing specific options in the configure phase. What’s important, both enabling and disabling features requires rebuilding the program in question because of code branches being switched. Thus, it’s perfectly fine if changing USE flags implies rebuilding the package.
Sadly, when it comes to optional runtime dependencies, USE flags are not a perfect solution. «Switching» such a dependency doesn’t require rebuilding the program anymore. It’s usually not even switching — the program can determine in runtime whether a particular dependency is available, and either enable or disable respective features. Simple like that.
If one decides to use USE flags for that, they become partially meaningless. Unless flags start stripping off the code (which is a bad idea), feature availability is dependency- rather than flag-based. So,
USE=-ssl is irrelevant if, say,
pyopenssl is installed. What’s even worse, flag imply needless rebuilding of such packages just to pull in an additional dependency.
The simple hack — pkg_postinst() messages
The simplest solution right now is just listing the suggested dependencies in
pkg_postinst() messages. Combined with
has_version helper, those messages can give a pretty nice output, pointing out already installed packages — just take a look at
Of course, it’s not a real solution, rather relying on user doing the hard work. The biggest disadvantage is that the dependencies are often going to end up in @world. And then, if user decides to unmerge our package, portage is unable to find and unmerge them as well.
The SDEPEND solution
A pretty common idea is to establish a new variable called
SDEPEND (for «suggested»). Such a variable would simply list relevant dependencies, and let portage handle the UI part somehow. It is a minimalistic solution, quite consistent with other parts of PMS. Sadly, it has a few big shortcomings.
First, using our current dependency syntax, you can’t specify that a particular feature requires more than one package; in other words, that two or more suggested dependencies are supposed to be pulled in together. Of course, solving this one would be pretty easy — e.g. by allowing grouping them with parantheses.
A much more important issue is describing what particular dependencies do. Although sometimes this could be guessed by package descriptions pretty well, usually a more friendly text would be great. So, we end up having to implement that somehow.
And that’s usually when Ciaran comes in with ugly exherbism
DEPENDENCIES. Sure, it solves most of the issues pointed out here but, hell, do we really want such a thing? Isn’t dependency syntax obscure enough already?
And it’s all rather dependency-oriented. In other words, package comes first, then goes the feature description. «Pass
dev-python/python-gnutls to enable secure connections support». I don’t think that’s the most user friendly solution.
The USE flag solution
Another solution is brining a new category of USE flags. It’s not important whether they would be specified using a special variable, common
USE_EXPAND or another magical features. In fact, that could be a thing totally separate from USE flags. The point is that some of the package flags would be runtime-switchable.
Unlike traditional USE flags, such flags wouldn’t be stored in vdb. They would be evaluated in place instead, using
package.use or similar files, and the dependency tree would use current state of such flags. Of course, they would be allowed for
PDEPEND) use only.
Why reuse USE flags for that? Because it’s the most user-friendly solution. User doesn’t have to learn anything new. He/she enables a flag, does
emerge -vDtN @world and notices that new dependencies are pulled in but the package doesn’t have to be rebuilt for that.
If we just add some additional magic for regular USE flags, enabling run-time dependant SSL support could be exactly the same as enabling build-time one — even using the same
And we could basically even give «backwards» support for older EAPIs. Package managers not supporting the new feature would simply treat runtime-switchable USE flags as regular USE flags, requiring rebuilds of the package.