Cabal2nix

hackage release stackage LTS package stackage Nightly package Continous Integration

cabal2nix converts a single Cabal file into a single Nix build expression. For example:

$ cabal2nix cabal://mtl
{ mkDerivation, base, lib, transformers }:
mkDerivation {
  pname = "mtl";
  version = "2.2.1";
  sha256 = "1icdbj2rshzn0m1zz5wa7v3xvkf6qw811p4s7jgqwvx1ydwrvrfa";
  libraryHaskellDepends = [ base transformers ];
  homepage = "http://github.com/ekmett/mtl";
  description = "Monad classes, using functional dependencies";
  license = lib.licenses.bsd3;
}

Cabal files can be referred to using the magic URL cabal://NAME-VERSION, which will automatically download the file from Hackage. Alternatively, a direct http://host/path/pkg.cabal URL can be provided, as well as a file:///local/path/pkg.cabal URI that doesn’t depend on network access. However, if the source hash is not already in cabal2nix’s cache or provided using the --sha256 option, cabal2nix still needs to download the source code to compute the hash, which still causes network traffic. Run the utility with --help to see the complete list of supported command-line flags.

Detailed instructions on how to use those generated files with Nix can be found at https://haskell4nix.readthedocs.io/nixpkgs-users-guide.html#how-to-create-nix-builds-for-your-own-private-haskell-packages.

cabal2nix can also build derivations for projects from other sources than Hackage. You only need to provide a URI that points to a cabal project. The most common use-case for this is probably to generate a derivation for a project on the local file system:

$ cabal get mtl-2.2.1 && cd mtl-2.2.1
$ cabal2nix .
{ mkDerivation, base, lib, transformers }:
mkDerivation {
  pname = "mtl";
  version = "2.2.1";
  src = ./.;
  libraryHaskellDepends = [ base transformers ];
  homepage = "http://github.com/ekmett/mtl";
  description = "Monad classes, using functional dependencies";
  license = lib.licenses.bsd3;
}

This derivation will not fetch from hackage, but instead use the directory which contains the derivation as the source repository.

cabal2nix currently supports the following repository types:

  • directory
  • source archive (zip, tar.gz, …) from http or https URL or local file.
  • git, mercurial, svn or bazaar repository

hackage2nix

This repository also contains, in the hackage2nix/ directory, the tool to update the Haskell packages in nixpkgs. It has its own README there.

Building

cabal2nix is built using cabal-install, like you’d expect, and you are free to use your favourite way of setting up a Haskell development environment.

Since cabal2nix is quite intertwined with the packages distribution-nixpkgs and hackage-db, we recommend setting up a shared development environment for the three packages like so:

$ mkdir /path/to/cabal2nix-root && cd /path/to/cabal2nix-root
$ # clone repositories, note that you may need to checkout an
$ # older tag for some depending on breaking changes on master.
$ git clone https://github.com/NixOS/cabal2nix.git
$ git clone https://github.com/NixOS/hackage-db.git
$ git clone https://github.com/NixOS/distribution-nixpkgs.git
$ # setup development environment with shellFor
$ cat > shell.nix << EOF
# assumes nix{os,pkgs}-unstable
{ pkgs ? import <nixpkgs> {} }:

pkgs.haskellPackages.shellFor {
  packages = p: [
    p.cabal2nix-unstable
    p.distribution-nixpkgs
    p.hackage-db
  ];

  # for running doctests locally
  nativeBuildInputs = [
    pkgs.haskellPackages.doctest
  ];

  # set environment variable, so the development version of
  # distribution-nixpkgs finds derivation-attr-paths.nix
  distribution_nixpkgs_datadir = toString ./distribution-nixpkgs;
}
EOF
$ # tell cabal about local packages
$ cat > cabal.project << EOF
packages: ./*/*.cabal
EOF
$ # test our new development environment
$ nix-shell --run "cabal v2-build exe:cabal2nix exe:hackage2nix"

Changes

Revision History for cabal2nix

2.19.0

Note that some of the API has also changed in a breaking manner because of the upgrade to distribution-nixpkgs 1.7.0, see #506.

  • Only use hpack when building if no cabal file is found for the package to process. See also #508.

  • hackage2nix now supports arbitrary Nix-style platform tuples in unsupported-platforms (including the new aarch64-darwin) as well as nixpkgs platform groups which are denoted as e. g. platforms.darwin and can be used instead of platform tuples. See also #506. API breaking change: The IsString instance for Platform in Distribution.Nixpkgs.Haskell.OrphanInstances has been removed.

  • The new hackage2nix supported-platforms configuration field allows prescribing a specific list of platforms to set in the package’s platforms meta attribute. unsupported-platforms are now translated to badPlatforms instead of being subtracted from platforms. See also #506 and #560. API Breaking Change for Distribution.Nixpkgs.Haskell.FromCabal.Configuration.

  • cabal2nix will no longer emit a dependency on webkitgtk24x-gtk{2,3} if it detects the older 3.0 API of WebKit being used. Nixpkgs hasn’t contained this package for a few years now due to security vulnerabilities and the packages still using it on Hackage are unmaintained. If you have a legacy project built with an old version of nixpkgs, either don’t upgrade cabal2nix or emulate the old behavior using overrides. See also #521.

  • If the input cabal file declares just a single executable, the mainProgram meta attribute will be set in the resulting Nix expression. See also #506 and #557.

  • If cabal2nix (or hackage2nix) doesn’t recognize the license of a package, it’ll still assume that it’s free and enable building on Hydra (i. e. use the default value of hydraPlatforms). This is done because Hackage requires uploaded packages to be open source. You may need to keep this change in mind, however, if you use cabal2nix for packaging unfree software. See also #520. isFreeLicense has changed semantically as a result.

  • Argument parsing logic in cabal2nix has been refactored in #544. API breaking change for the following modules:

    • Cabal2nix
    • Distribution.Nixpkgs.Fetch
    • Distribution.Nixpkgs.Haskell.Derivation (removed instance)
    • Distribution.Nixpkgs.Haskell.PackageSourceSpec
  • Update handling of Lua bindings to reflect current state upstream. See #527 and #547.

2.18.0

  • Support GHC 9.0.x and Cabal 3.4.0.0, API breaking change (See #503)
  • Fix fetching remote archives: Previously they weren’t properly unpacked, API breaking change (See #455)
  • Resolution of system dependency attribute names in nixpkgs
    • Update changed upstream attribute names, reflect deprecations
    • Fix hackage2nix not resolving certain attribute names if multiple attribute names referred to the same derivation. (See #492 and distribution-nixpkgs#10)
  • hackage2nix: accept multiple config files at the command line given by specifying --config more than once (See #494)