
On 12/11/2016 11:53 AM, Tobias Dammers wrote:
The pipe dream would be for those dependencies to be optional *at run time*, such that the application would test for their presence on startup, or load them dynamically when and if they're needed. However, I'm also fine with making them compile-time feature toggles, such that users can enable only the ones they need. Doing some sort of autotools-style dependency discovery would of course be cool as well (i.e., only enable mysql support if libmysqlclient is present).
This actually isn't ideal, because once everything is installed, you have no idea what is important. Can I uninstall libfoo-mysql? Well, bar-utils is making use of it, but it always does when libfoo-mysql is present, so there's no way to tell if the mysql support is important (i.e. whether or not the user wanted it when he installed bar-utils). The end result is that every "optional" dependency has to remain installed unconditionally forever, because removing them might break software that auto-detects their presence. (Google: "automagic dependencies")
So the broad question is, which of these are realistic, and how would I go about it?
And, regarding feature toggles, this bit in the Cabal FAQ baffles me a little:
Question: I like to let the user enable extended functionality using a Cabal flag. Is this the right way?
Answer: Certainly not. Since other packages can distinguish packages only according to their name and their version, it is not a good idea to allow different APIs for the same package version. Cumbersome as it is you have to move extra features to a separate package.
This is a cabal-install or stack deficiency, not one inherent to Haskell packages or package management in general. The real solution: use a feature flag, and then use a package manager that knows what to do with them. As an added bonus, a real package manager can handle the C library dependencies as well, and your application won't break randomly when those libraries move around or disappear.