Stack: How can I use a multi-package dependency in `Setup.hs`? - haskell

I have a stack multi-package project where the "multi-package" is zip-conduit-0.2.2.2 (I needed to tweak some dependency versions to get it to compile with nightly-2015-10-12).
I use zip-conduit in the main package and I also want to in Setup.hs in order to be able to package up zip files.
I have build-type: Custom in my cabal file and stack build attempts to build Setup.hs. The problem is that building Setup.hs cannot find the dependency zip-conduit-0.2.2.2.
Can I use a multi-package dependency in Setup.hs? If so how? and if not, what is my alternative?
Note: I have seen this reference https://github.com/commercialhaskell/stack/pull/899, but I don't understand it.

It looks like you need to set the explicit-setup-deps setting to true for that package. It's unfortunate that Stack can't handle this situation automatically, but without dependency information in .cabal files, there seems to be no alternative.
See the linked issues from the documentation if you're interested in the history here.

I don't think it is possible to declare package dependencies for Setup.hs itself.
Some ideas:
Require that the dependent packages have already been installed.
Have Setup.hs shell out to an external command to perform the zipping, and just require that the external command has to exist.
Make the installer program an additional exe target in the cabal file. Before proceeding with the build of the library, Setup.hs can build the installer program target, then build the library, then use the built installer exe to install the library.

Related

Cabal - add build dependency with Cabal instead of manually mangling with the file

Do I need to manually edit the *.cabal file's build-depends section to add package as a project dependency?
Or perhaps there is a more convenient way that is not as error prone as manually mangling with build files is.
Thinking about functionality that pretty much any package manager I used has, namely
apt install
npm i
nuget install
Install Package
and so on. Does such functionality exist in Cabal?
There is no better way at the moment. The answer #danidiaz gave is essentially correct -- cabal-edit will automatically update cabal files for you. The plan is to import similar functionality into cabal directly. This was remains blocked on an exactprinter that can parse and emit cabal files precisely -- and work on that exactprinter is now underway.

Can I use cabal to handle non-Haskell libraries?

There have been attempt in other package managers to build brigdes to other ecosystems. E.g., there is composer-npm-bridge, which allows to pull packages from node registry into a PHP project. Is it possible to build something like this using cabal? More concretely, how would one go about pulling packages from luarocks into a Haskell project?
It is in principle possible: with build-type: custom, cabal will compile and run your Setup.hs in place of its own build mechanisms, and you can put arbitrary Haskell code in Setup.hs. Alternately, if you can fit your setup process into the usual configure-make-make install dance, then the build-type: configure option may be just the ticket.
See the user's guide for more complete details on these configuration options.

Installing local package with Stack

Is it possible to install package from sources with something similar to stack build package-name? (latter works with packages on Stackage, but not with custom ones)
Um, stack build (within the source directory)?
Stack doesn't really have a notion of installing libraries though, it only installs executables. To “install” locally-sourced packages, you need to specify what for you want them installed: add them as dependencies to another project, via a location: field in the packages: field in that project's stack.yaml file.
That's arguably sensible since, one might say, there's nothing you can do with an installed library except invoking it in another Haskell project (or in a REPL, which you can get with stack ghci). I personally don't hold with that though, I like actually being able to say install that library now. Which is one of the reasons I have always stuck to good old cabal-install rather than Stack. With that, you can just
cabal install
from within the source directory.
Cabal-install has often been criticised: its local installs can easily get out of sync and then you have weird dependency conflicts and need to rebuild lots of stuff. I never found this that much of a problem, and anyway this has been adressed in recent Cabal through Nix-style builds, which never produce conflicts.

How to get stack to save dependencies?

I'm using the stack install command to save dependencies for a new project. How do I get it to save those dependencies into stack.yaml? Unless I'm missing something, I can't see where stack is recording the project dependencies and I can't seem to find anything in a docs about this.
You still keep your dependencies in a .cabal file. From the Stack FAQ:
A .cabal file is provided for each package, and defines all package-level metadata just like it does in the cabal-install world: modules, executables, test suites, etc. No change at all on this front.
A stack.yaml file references 1 or more packages, and provides information on where dependencies come from.
If you need additional versions of dependencies than the LTS Haskell snapshot you're using, you'll add them to the extra-deps portion of the stack.yaml file.

Cabal - Expose all modules while building library

Is it possible to tell Cabal to expose all modules while building a library?
Right now I have to provide very long list of modules in the exposed-modules cabal configurtion file section.
The modern answer is stack + hpack instead of using explicit cabal config. It could automatically expose package modules and provides many other enhancements.
You have to list all modules in the cabal configuration file. In your case, you just put the list of modules after exposed-modules:. There is no simpler way to write a list of modules.
Cabal cannot automatically find the files that are part of an executable or library, so it relies on the list of modules in the configuration file. Unlike GHC, cabal cannot find modules based on import statements in the source code. If you don't list every module, then you may be able to build the project (because GHC can find source files), but other commands such as cabal sdist will not access the source files that aren't listed.

Resources