Skip to content

Interface for system package manager to execute build plan #3882

Open
@Ericson2314

Description

@Ericson2314

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:

  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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions