haskell / haskell/cabal

Interface for system package manager to execute build plan

Open
#3,882 38 comments 0 reactions 0 assignees View on GitHub
cabal-install: v2-build system old-milestone: ⊥ type: enhancement
Dominant language
Haskell
Stars
1.7k
Forks
750
Avg merge
4d 3h
Merged PRs (30d)
28

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](https://github.com/ezyang/ghc-proposals/blob/master/proposals/0000-componentized-cabal.rst#proposed-change-cabal-install) 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:
1. 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
2. `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?
3. 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, but `cabal configure` can anticipate when they will be looked-for.)
- TODO: Deps on other "install items"
- TODO: hackage urls + hash sufficient for Nix to fetch
4. 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 use `builtins.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 pass `cabal new-configure` enough so that the `./Setup` flags do not need to be modified.
# Work to be done
- [x] https://github.com/haskell/cabal/issues/1493: host vs target tools

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.