13

I am attempting to build my haskell project on NixOS.

Running $ stack build gives the following error.

$ stack build
error: attribute ‘ghc822’ missing, at (string):1:53
(use ‘--show-trace’ to show detailed location information)

What does this error mean and how could I proceed? When I run $ stack build --show-trace as suggested, I get the following output, which I do not understand either.

$ stack build --show-trace
Invalid option `--show-trace'

Usage: stack build [TARGET] [--dry-run] [--pedantic] [--fast]
                   [--ghc-options OPTIONS] [--flag PACKAGE:[-]FLAG]
                   ([--dependencies-only] | [--only-snapshot] |
                   [--only-dependencies]) ([--file-watch] | [--file-watch-poll])
                   [--exec CMD [ARGS]] [--only-configure] [--trace] [--profile]
                   [--no-strip] [--[no-]library-profiling]
                   [--[no-]executable-profiling] [--[no-]library-stripping]
                   [--[no-]executable-stripping] [--[no-]haddock]
                   [--haddock-arguments HADDOCK_ARGS] [--[no-]open]
                   [--[no-]haddock-deps] [--[no-]haddock-internal]
                   [--[no-]haddock-hyperlink-source] [--[no-]copy-bins]
                   [--[no-]copy-compiler-tool] [--[no-]prefetch]
                   [--[no-]keep-going] [--[no-]force-dirty] [--[no-]test]
                   [--[no-]rerun-tests] [--ta|--test-arguments TEST_ARGS]
                   [--coverage] [--no-run-tests] [--[no-]bench]
                   [--ba|--benchmark-arguments BENCH_ARGS] [--no-run-benchmarks]
                   [--[no-]reconfigure] [--[no-]cabal-verbose]
                   [--[no-]split-objs] [--skip ARG] [--help]
  Build the package(s) in this directory/configuration

I tried changing my channel to nixos-17.09 instead of nixos-unstable (and running nix-channel --update), but still get the same error.

Output of $ nix-channel --list is shown below.

$ nix-channel --list
stack https://nixos.org/channels/nixos-17.09
nixos https://nixos.org/channels/nixos-17.09

The output of $ nix-env -qaPA 'nixos.haskell.compiler' shows ghc822 to be found.

$ nix-env -qaPA 'nixos.haskell.compiler'
warning: name collision in input Nix expressions, skipping ‘/home/matthew/.nix-defexpr/channels_root/nixos’
nixos.haskell.compiler.ghc6102Binary           ghc-6.10.2-binary
nixos.haskell.compiler.ghc704                  ghc-7.0.4
nixos.haskell.compiler.ghc704Binary            ghc-7.0.4-binary
nixos.haskell.compiler.ghc7102                 ghc-7.10.2
nixos.haskell.compiler.integer-simple.ghc7102  ghc-7.10.2
nixos.haskell.compiler.ghc7103                 ghc-7.10.3
nixos.haskell.compiler.integer-simple.ghc7103  ghc-7.10.3
nixos.haskell.compiler.integer-simple.ghc742   ghc-7.4.2
nixos.haskell.compiler.ghc742                  ghc-7.4.2
nixos.haskell.compiler.ghc742Binary            ghc-7.4.2-binary
nixos.haskell.compiler.ghc763                  ghc-7.6.3
nixos.haskell.compiler.ghc783                  ghc-7.8.3
nixos.haskell.compiler.integer-simple.ghc783   ghc-7.8.3
nixos.haskell.compiler.ghc784                  ghc-7.8.4
nixos.haskell.compiler.integer-simple.ghc784   ghc-7.8.4
nixos.haskell.compiler.ghc801                  ghc-8.0.1
nixos.haskell.compiler.integer-simple.ghc801   ghc-8.0.1
nixos.haskell.compiler.ghc802                  ghc-8.0.2
nixos.haskell.compiler.integer-simple.ghc802   ghc-8.0.2
nixos.haskell.compiler.integer-simple.ghc821   ghc-8.2.1
nixos.haskell.compiler.ghc821                  ghc-8.2.1
nixos.haskell.compiler.integer-simple.ghc822   ghc-8.2.2
nixos.haskell.compiler.ghc822                  ghc-8.2.2
nixos.haskell.compiler.integer-simple.ghcHEAD  ghc-8.3.20170808
nixos.haskell.compiler.ghcHEAD                 ghc-8.3.20170808
nixos.haskell.compiler.ghcjs                   ghcjs-0.2.0
nixos.haskell.compiler.ghcjsHEAD               ghcjs-0.2.020170323
nixos.haskell.compiler.jhc                     jhc-0.8.2
nixos.haskell.compiler.uhc                     uhc-1.1.9.4

I installed ghc8.2.2 via $ nix-env -iA nixos.haskell.compiler.ghc822, and $ ghc --version now returns

$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 8.2.2

However, I still get the error error: attribute ‘ghc822’ missing, at (string):1:54 when attempting to run $ stack build.

Also, I attempted to see what ghc version my stack is using after this install, and this led to the same attribute ‘ghc822’ missing error.

$ stack ghc -- --version
error: attribute ‘ghc822’ missing, at (string):1:54
(use ‘--show-trace’ to show detailed location information)
mherzl
  • 5,624
  • 6
  • 34
  • 75
  • 1
    Try running `nix-env -qaPA 'nixos.haskell.compiler'` and see if `8.2.2` was found or not. I am using `nixos-unstable` and I have `ghc822`. – wizzup Dec 22 '17 at 11:14
  • @wizzup the output of that command does show `ghc822` (question edited to show that command's output). – mherzl Dec 22 '17 at 15:27
  • 1
    Then I have no idea. You may try adding `--nix` to stack commands. for example, `stack --nix build`. – wizzup Dec 23 '17 at 05:18

5 Answers5

7

It seems like your stack wants to retrieve the haskell.packages.ghc822 attribute or perhaps haskell.compiler.ghc822, which is not present in your version of <nixpkgs>.

Please check your channel configuration using sudo nix-channel --list (NixOS) or nix-channel --list. Releases 17.03 and older do not have this attribute. 17.09 and unstable should be fine. To switch your default <nixpkgs> to 17.09, note the name of the channel and run

nix-channel --add https://nixos.org/channels/nixos-17.09 <NAME>

Also run nix-channel --update to make sure you have a recent version. GHC 8.2.2 was added on Oct 31st.

If you don't want to change your channel configuration, I suppose you can set the NIX_PATH environment variable

NIX_PATH=nixpkgs=https://github.com/NixOS/nixpkgs-channels/archive/nixos-unstable.tar.gz stack build
Robert Hensing
  • 6,708
  • 18
  • 23
  • 1
    My `nix-channel` was `nixos-unstable`. For good measure I changed it to `nixos-17.09` per these instructions (and ran `nix-channel --update`) but still get the same error. – mherzl Dec 21 '17 at 14:40
  • 1
    Searching for `ghc` in the results of `nix-env -qaP '*' --description` I do not see `ghc-8.2.2` (only `ghc-8.0.2`). – mherzl Dec 21 '17 at 14:59
  • 2
    Perhaps the reference to nixpkgs is made by other means, such as the `nix`/`path` variable in `stack.yaml`, or `nix`/`shell-file`? See https://github.com/commercialhaskell/stack/blob/master/doc/nix_integration.md – Robert Hensing Dec 21 '17 at 15:14
  • 2
    I replaced `resolver: lts-10.2` by `lts-9.1` in `stack.yaml` to work around the issue. – palik Dec 31 '17 at 23:43
5

Another option is to use a shell.nix. nixos-18.03 comes with ghc 8.2.2, so you can create a shell.nix like:

with import (builtins.fetchGit {
    url = https://github.com/NixOS/nixpkgs-channels;
    ref = "nixos-18.03";
    rev = "cb0e20d6db96fe09a501076c7a2c265359982814";
}) {};

haskell.lib.buildStackProject {
    name = "my-project";
    buildInputs = [ ghc <otherlibs-here> ];
}

And add the following to your stack.yaml:

nix:
  shell-file: shell.nix

Then stack build as usual.

Steve Chavez
  • 931
  • 10
  • 13
3

You can provide an old GHC version using a shell.nix file place in the root of your project:

with import (fetchTarball https://github.com/NixOS/nixpkgs/archive/83b35508c6491103cd16a796758e07417a28698b.tar.gz) {};
let ghc = haskell.compiler.ghc802;
in haskell.lib.buildStackProject {
    inherit ghc;
    name = "myEnv";
    buildInputs = [ pcre ];
}

Use a tar url from https://github.com/NixOS/nixpkgs/releases for a version of nixpkgs that contains the GHC version you need.

Then run nix-shell in the root of the project. This will put you into a shell in which you can perform stack build successfully since it would have access to the correct GHC version.

Răzvan Flavius Panda
  • 21,730
  • 17
  • 111
  • 169
1

As palik commented, changing the resolver version -- in my case changing

resolver: lts-11.3

to

resolver: lts-9.1

in stack.yaml is a work-around. I do not know what the deeper issue is but would be interested to know.


Update: this post provides a thorough explanation with excellent tips on how to use stackage and nix in concert, including how to reach agreement between package versions of the stack resolver and nix channel.


How to know which resolver to specify in stack.yaml?

Go to this url, which shows stackage snapshots containing ghc: https://www.stackage.org/package/ghc/snapshots

This will tell you the resolver corresponding to the ghc version you have. For example, I have ghc 8.10.7,

$ ghc --version
The Glorious Glasgow Haskell Compilation System, version 8.10.7

and doing a find '8.10.7' on that page shows me that corresponds to LTS Haskell 18.28 (ghc-8.10.7). So I would specify resolver: lts-18.28 in my stack.yaml.

(How to find resolvers for a given package was found in an answer here.)

mherzl
  • 5,624
  • 6
  • 34
  • 75
  • 1
    I had a similar issue, and like you, changing my `resolver` from in my case `nightly-2018-05-21` to `lts-11.15` fixed it as well. Thank you! – Kiara Grouwstra Jun 30 '18 at 20:01
  • If you have trouble identifying which resolver to set, you can try `stack config set resolver lts`, as described here: https://docs.haskellstack.org/en/stable/faq/#what-version-of-ghc-is-used-when-i-run-something-like-stack-ghci. – mherzl Sep 05 '20 at 18:41
0

based on @steve-chávez answer

stack.yaml

resolver: lts-13.19
system-ghc: true
install-ghc: false

nix:
  enable: true
  path: [nixpkgs=./nix/nixpkgs/default.nix]
  shell-file: shell.nix

nix/nixpkgs/default.nix

let
  spec = builtins.fromJSON (builtins.readFile ./revision.json);

  src = import <nix/fetchurl.nix> {
    url = "https://github.com/${spec.owner}/${spec.repo}/archive/${spec.rev}.tar.gz";
    inherit (spec) sha256;
  };
  nixcfg = import <nix/config.nix>;

  nixpkgs = builtins.derivation {
    system = builtins.currentSystem;
    name = "${src.name}-unpacked";
    builder = builtins.storePath nixcfg.shell;
    inherit src;
    args = [
      (builtins.toFile "builder" ''
        $coreutils/mkdir $out
        cd $out
        $gzip -d < $src | $tar -x --strip-components=1
      '')
    ];
    coreutils = builtins.storePath nixcfg.coreutils;
    tar = builtins.storePath nixcfg.tar;
    gzip = builtins.storePath nixcfg.gzip;
  };
in
  import nixpkgs

nix/nixpkgs/update.sh

#!/usr/bin/env nix-shell
#!nix-shell -i bash -p nix curl jq

SCRIPT_DIR=$(dirname "$(readlink -f "$BASH_SOURCE")")

owner="nixos"
repo="nixpkgs-channels"
rev="nixos-unstable"

full_rev=$(curl --silent https://api.github.com/repos/$owner/$repo/git/refs/heads/$rev | jq -r .object.sha)

echo "full_rev=$full_rev"

expected_sha=$(nix-prefetch-url https://github.com/$owner/$repo/archive/$full_rev.tar.gz)

cat >"$SCRIPT_DIR/revision.json" <<EOL
{
  "owner":  "$owner",
  "repo":   "$repo",
  "rev":    "$full_rev",
  "sha256": "$expected_sha"
}
EOL

shell.nix

{
  #
  # there are 2 ways of using stack with nix
  # - define custom packages in `stack.yaml` `packages` option (https://docs.haskellstack.org/en/stable/nix_integration/#additions-to-your-stackyaml)
  # - define custom package in `shell.nix` AND `shell-file: ...` in `stack.yaml` (https://docs.haskellstack.org/en/stable/nix_integration/#additions-to-your-stackyaml)
  #
  # we are using second option

  ghc # stack expect this file to define a function of exactly one argument that should be called ghc
}:


let
  # pkgs = import ./nix/nixpkgs/default.nix {}
  pkgs = import <nixpkgs> {};
in

with pkgs;

haskell.lib.buildStackProject {
  inherit ghc;
  name = "myEnv";
  buildInputs = [ cabal-install ];
}
srghma
  • 4,770
  • 2
  • 38
  • 54