haskell / cabal

Official upstream development repository for Cabal and cabal-install
https://haskell.org/cabal
Other
1.61k stars 691 forks source link

cabal flags for dependencies #8643

Open coot opened 1 year ago

coot commented 1 year ago

There seem to be no way to specify cabal flag for dependencies. In ghc-tags and ghc-tags-plugin I would like to use ghc-tags-core as a dependency but:

The cabal's file build-depends only allow to specify version constraints. cabal.project file allows to include constraints but it's not distributed through hackage users will need to use:

cabal install -f +ghc-lib ghc-tag
cabal install -f -ghc-lib ghc-tags-plugin

which is far from perfect (because cabal install ghc-tag would fail or the other one depending what is the default value for ghc-lib flag). Is there a way around this? If not what would be the right solution:

gbaz commented 1 year ago

Sorry, this answer isn't especially helpful, but its pretty hardwired into the design of cabal that requiring a dependency should not require it be configured with any specific flags, and that its a mistake to do so.

There are solver hacks that exist (via coupling flags to some 'extra' dependency) so that the solver is forced to solve for flags uniformly across multiple packages, if you control them all. However, I wouldn't recommend this. The unfortunate answer is probably that if a package is sufficiently distinct depending on the choice of flags that it can't be used "like for like" then it should probably be two packages.

coot commented 1 year ago

In this case it's easy to build ghc-tags-core with either ghc or ghc-lib as a dependency. (ghc-tag and ghc-tags-plugin then depends on ghc-tags-core). I'd like to avoid two packages (as that would just duplicate the code without much benefit).

There are solver hacks that exist (via coupling flags to some 'extra' dependency) so that the solver is forced to solve for flags uniformly across multiple packages, if you control them all.

@gbaz do you have any example by hand?

clintonmead commented 1 year ago

@gbaz @coot I'd also be interested in such an example, in particular one that works for a package, and doesn't require changes on a .project level.

gbaz commented 9 months ago

Assume foo depends on bar but only with flag barflag set. Now, you can create a new package barflag with two versions, now set bar so that the flag barflag requires the package barflag-1 and the negation of barflag requries the package barflag-2, you can have foo depend on either barflag-1 or barflag-2 to force bar to be compiled with or without the flag. (note you can do this with any "safe" simple package on hackage with at least two versions, not necessarily one just for this purpose). This is as I said, hacky, and not recommended :-)

noughtmare commented 3 months ago

This seems to be a duplicate of, or at least related to #2821.