Files
haskell.nix/docs/user-guide/projects.md
T
Moritz AngermannandGitHub 5884ab02be Overlays (#261)
The Overlays branch

This is a major reorganization in how haskell.nix is used, and marks our 1.0 release.
The branch doesn't build due to numerous issues that we believe to be with the CI
and not this branch. We expect only very minor adjustments prior to calling this the
official 1.0 release.

* Move iohk-nix patches into haskell.nix

This moves the customizations we did in iohk-nix
into haskell.nix via overlays and config.

Add bootPkgs logic

this moves the nuking of bootPkgs where it belongs. This should eventually still be
removed and replaced by a proper solution, that doesn't require the nuking of
bootPkgs.

Allow us to bootstrap binary ghcs and a cabal-install

With this we can do the following:

```
$ nix repl compiler/old-ghc-nix
nix-repl> :b (let pkgs = import <nixpkgs> {}; in with import ./. {}; import ./compiler/bootstrap/cabal-install.nix { inherit (pkgs) fetchurl stdenv zlib; inherit hackage
; ghc = ghc844; src = pkgs.fetchurl { url = "https://github.com/haskell/cabal/archive/Cabal-v3.0.0.0-rc3.tar.gz"; sha256 = "1zl2mgg8307ykq3v8nmafc6zdhhj1cw7w8ffpap16dsm6
5lbnx33"; }; })
```

which wile it may look daunting, will allow us to bootstrap a
cabal-install with a ghc. From that point onwards, we should be able to
build any hackage package via haskell.nix.

Pass through cabal-install version

Better threading of arguments.

Add bootstrap overlay

Allow alex + happy to be built

This still has a wart: we need nix-tools, and for that we use the ghc865 from
nixpkgs. Ideally we'd build nix-tools against a specific ghc, but then
we'd need a build expression for that.

Make ghcjs work

Building something like this:
```
 nix build '(with import ./. { nixpkgs = ../nixpkgs; nixpkgsArgs = { crossSystem = { config = "js-unknown-ghcjs"; }; }; }; (haskell-nix.hackage-package { name = "hello"; version = "1.0.0.2"; })).components.exes.hello'
```
will now work. Assuming `nixpkgs` has been appropriately patched to support the `js-unknown-ghcjs` triple.

Also: this will need an additional `Cabal` patch, to make `Cabal` understand what it needs to do with: `dist/build/hello/hello: copyFile: does not exist (No such file or directory)`

It needs to learn that `dist/build/hello/hello.jsexe` is what it wants to copy and that that is a directory.  Luckily we do have some code in Cabal already that does this for `.exe` on windows.

Build `js-unknown-ghcjs` packages with haskell.nix

Using the following expression:
```
with import ./. { nixpkgs = ../nixpkgs; nixpkgsArgs = { crossSystem = { config = "js-unknown-ghcjs"; }; }; };
let Cabal = buildPackages.haskell-nix.hackage-package {
    name = "Cabal"; version = "2.4.1.0";
    modules = [
        { packages.Cabal.patches = [ ./Cabal-install-folder.diff ]; }
    ];
}; in
(haskell-nix.hackage-package {
    name = "hello"; version = "1.0.0.2";
    modules = [
    	    ({config, ... }:{ packages.hello.package.setup-depends = [ Cabal ]; })
    ];}).components.exes.hello
```
in a `test.nix` file. And running
```
nix build -f ./test.nix
```
on it, will produce
```
./result
├── bin
│   └── hello.jsexe
│       ├── all.js
│       ├── all.js.externs
│       ├── index.html
│       ├── lib.js
│       ├── manifest.webapp
│       ├── out.frefs.js
│       ├── out.frefs.json
│       ├── out.js
│       ├── out.stats
│       ├── rts.js
│       └── runmain.js
└── share
    └── doc
        └── x86_64-linux-ghc-8.6.5
            └── hello-1.0.0.2
                └── LICENSE

6 directories, 12 files
```
2019-10-21 20:07:58 +08:00

2.7 KiB

How to replace IFDs with intermediate nix files

We believe that imports from derivations (IFDs) provide tremendous value in nix and the aversion towards them stems mostly from poor tooling and ci support for them. We do not believe that poor tooling or ci support should cripple nix capability of abstraction. Hence haskell.nix makes excessive use of IFDs.

We do note however that there are users who prefer to have IFD-free expressions. For this group of users we detail how to expand the IFD dependent high level functions into their IFD free building blocks.

The general structure will be the same, independent of the use of Stack or Cabal.

Let us assume for now that we have already generated a pkgs.nix expression (see the links bellow). The following file then produces a package set:

# default.nix
let
  # Import the Haskell.nix library,
  pkgs = import <nixpkgs> (import builtins.fetchTarball https://github.com/input-output-hk/haskell.nix/archive/master.tar.gz);

  # Import the file you will create in the stack-to-nix or cabal-to-nix step.
  my-pkgs = import ./pkgs.nix;

  # Stack projects use this:
  pkgSet = pkgs.haskell-nix.mkStackPkgSet {
    stack-pkgs = my-pkgs;
    pkg-def-extras = [
      # these extras will provide additional packages
      # ontop of the package set.  E.g. extra-deps
      # for stack packages. or local packages for
      # cabal.projects
    ];
    modules = [
      # specific package overrides would go here
      # example:
      #  packages.cbors.package.ghcOptions = "-Werror";
      #  packages.cbors.patches = [ ./one.patch ];
      #  packages.cbors.flags.optimize-gmp = false;
      # It may be better to set flags in stack.yaml instead
      # (`stack-to-nix` will include them as defaults).
    ];
  };

  # Cabal projects use this:
  pkgSet = pkgs.haskell-nix.mkCabalProjectPkgSet {
    plan-pkgs = my-pkgs;
    pkg-def-extras = [];
    modules = [
      # specific package overrides would go here
      # example:
      #  packages.cbors.package.ghcOptions = "-Werror";
      #  packages.cbors.patches = [ ./one.patch ];
      #  packages.cbors.flags.optimize-gmp = false;
      # It may be better to set flags in `cabal.project` instead
      # (`plan-to-nix` will include them as defaults).
    ];
  };

in pkgSet.config.hsPkgs // { _config = pkgSet.config; }

With this setup you can then start building the components of interest:

nix build -f default.nix $pkg.components.library

to build the library for $pkg or

nix build -f default.nix $pkg.components.exes.$exe

to build a specific executable. The same holds for test suites and benchmarks.