Description
Original Post
I wrote a fairly long email to the nix-dev list (http://lists.science.uu.nl/pipermail/nix-dev/2016-September/021765.html) proposing that cabal2nix
work from cabal-install
's build plans instead of the package cabal files themsevles. This would obviated needing to teach it to resolve configuring options etc, basically replicating Cabal. [The idea is of cabal-install resolving the plan and the system package manager executing the plan generalizes for any system package manager, not just Nix, hence not singling Nix out in the issue title.]
Reading the cabal-install section of the componentized Cabal proposal leads me to further propose that plan.json
(or whatever should be the interface between the system package manager and cabal-install) contain exactly the component dependency graph proposed in the RFC. This granularity would be nice for Nix for the same reason it is nice for cabal and stack---I personally will contest that playing around with some packages and then having to rebuild them to enable tests is quite annoying.
A final extension to that would be to extend Cabal itself to also work from these a single-component manifests. The default Setup binary would gain the ability to work from either a manifest--corresponding to a single component, or a bunch of manifests--corresponding to that component and its dependency closure. [I say either because I am not sure whether the new-* work affect Cabal or just cabal-install. If Cabal too, I assume the closure is needed, if just Cabal then the single component's manifest is probably fine.]
There are two advantages of this final bit. The first is that we currently only use Cabal, not cabal-install, in Nix Haskell packages, and this would allow us to continue doing that. That said, I'm not sure what the advantages of this current approach so this may not be good motivation. The second is were we also wanted to use stack to generate build plans, the component dependency dag is probably a good format for both to support (I speculate given that the componentization proposal was originally @snoyberg's idea). stack --nix
already exists but for reasons given in my mailing list post, I think the mechanism I'm describing would work strictly better.
Anyways, after writing the proposal for the Nix list, I thought it would be good to get the attention and opinion of upstream.
Current Plan for Nix
For non-local dev (packaging executables for nixpkgs), here is a sketch of the entire process:
- Make the
cabal.project
- Use
extra-packages:
for the executables, since they come from hackage - Use
compiler:
to specify the compiler so we don't it built at config time. - Ignore native deps
- Use
cabal new-configure
without any network access and limited FS access only to cabal-install's runtime deps + downloaded index- Neither the compiler, executable deps, or native library deps need to be built/exposed at this time.
- TODO some way to give cabal-install a nix-downloaded index, ideally without weakening with the TUF stuff. Maybe
.cabal/config
already handles this? I assume we can put the config elsewhere with a CLI flag?
- Resulting
plan.json
contains "install items" each with:- Basic metadata like package name, component name, and version
- Relevant calls to
./Setup
with all flags - TODO: pkg-config deps relevant to just this component. (
./Setup configure
is still responsible for checking whether those libraries are present, butcabal configure
can anticipate when they will be looked-for.) - TODO: Deps on other "install items"
- TODO: hackage urls + hash sufficient for Nix to fetch
- Turn
plan.json
into a package set where each "install item" becomes a derivation. Either this comparatively simple task is the new job of cabal2nix, or this is so simple we can just usebuiltins.fromJSON
and write in Nix.- Use Nix-style uniq ID's to replicate dependency graph structure.
- Fetch and unpack Hackage tarballs.
- Put the
./Setup
commands specified in the proper phases. Hopefully we passcabal new-configure
enough so that the./Setup
flags do not need to be modified.
Work to be done
- build Setup.hs with local compiler when cross-compiling #1493: host vs target tools