I don’t really understand how the default haskell.nix template works. There are a few different factors conspiring to make it incomprehensible:
flake.nix
:
{
# This is a template created by `hix init`
inputs.haskellNix.url = "github:input-output-hk/haskell.nix";
inputs.nixpkgs.follows = "haskellNix/nixpkgs-unstable";
inputs.flake-utils.url = "github:numtide/flake-utils";
outputs = { self, nixpkgs, flake-utils, haskellNix }:
let
supportedSystems = [
"x86_64-linux"
"x86_64-darwin"
"aarch64-linux"
"aarch64-darwin"
];
in
flake-utils.lib.eachSystem supportedSystems (system:
let
overlays = [ haskellNix.overlay
(final: prev: {
hixProject =
final.haskell-nix.hix.project {
src = ./.;
evalSystem = "x86_64-linux";
};
})
];
pkgs = import nixpkgs { inherit system overlays; inherit (haskellNix) config; };
flake = pkgs.hixProject.flake {};
in flake // {
legacyPackages = pkgs;
packages.default = flake.packages."hello:exe:hello";
});
# --- Flake Local Nix Configuration ----------------------------
nixConfig = {
# This sets the flake to use the IOG nix cache.
# Nix should ask for permission before using it,
# but remove it here if you do not want it to.
extra-substituters = ["https://cache.iog.io"];
extra-trusted-public-keys = ["hydra.iohk.io:f/Ea+s+dFdN+3Y/G+FDgSq+a5NEWhJGzdjvKNGv0/EQ="];
allow-import-from-derivation = "true";
};
}
- I initialize it using
nix flake init --template templates#haskell-nix --impure
. However, in theflake.nix
, it says
# This is a template created by `hix init`
This is a lie! I have never heard of hix, don’t have it installed, and certainly didn’t use it to initialise this template. It seems as though hix
is some kind of command line tool. I don’t understand why it’s being referenced in the template - it feels like a leaky abstraction. Do I need to now go and learn how to use this command line tool in order to understand how to use the flake I just initialized?
- I don’t know where to look for documentation.
overlays = [ haskellNix.overlay
(final: prev: {
hixProject =
final.haskell-nix.hix.project {
src = ./.;
evalSystem = "x86_64-linux";
};
})
];
I’m a bit hazy on how overlays work, so I don’t entirely understand what final.haskell-nix
is or how it relates to haskellNix
. It seems like the template is using a function haskell-nix.hix.project
. Where can I find documentation on this? The haskell.nix library reference doesn’t include any information on a hix
attribute, although it does mention a project
, is that the same thing? How would I know if it were?
-
nix flake show
doesn’t work.
⮞ nix flake show
path:/home/james/tmp/haskell-nix-template?lastModified=1690453162&narHash=sha256-ali7UKFmjtNSlTOQyvuduWharsgmfKtDWKsbxnY%2f+C0=
trace: No index state specified for haskell-project, using the latest index state that we know about (2023-03-01T00:00:00Z)!
error: cannot build '/nix/store/6kjv10ghqs2jwfbq6zlszp64i21xb9is-haskell-project-plan-to-nix-pkgs.drv' during evaluation because the option 'allow-import-from-derivation' is disabled
(use '--show-trace' to show detailed location information)
It seems as though there are some github issues relating to this (haskell.nix/issues/1711, nix/issues/4265)
The actual impetus behind this post was that I couldn’t figure out how to get the flake to provide a haskell library as well as an executable. I don’t really understand where the “hello:exe:hello” string comes from, or what its syntax is - what strings are valid to put between the colons. I tried the following:
⮞ git diff
diff --git a/flake.nix b/flake.nix
index d2b07fc..d96fb9a 100644
--- a/flake.nix
+++ b/flake.nix
@@ -29,6 +29,7 @@
legacyPackages = pkgs;
packages.default = flake.packages."hello:exe:hello";
+ packages.lib = flake.packages."hello:lib:hello-lib";
});
# --- Flake Local Nix Configuration ----------------------------
diff --git a/hello.cabal b/hello.cabal
index 0b7f34e..794af3f 100644
--- a/hello.cabal
+++ b/hello.cabal
@@ -14,7 +14,8 @@ stability: stable
homepage: http://www.haskell.org/hello/
synopsis: Hello World, an example package
category: Console, Text
-cabal-version: >= 1.6
+-- need this because "Internal libraries only supported with per-component builds."
+cabal-version: >= 1.8
build-type: Simple
Description:
@@ -37,3 +38,9 @@ executable hello
if flag(threaded)
ghc-options: -threaded
+
+library hello-lib
+ exposed-modules: Lib
+ build-depends: base >= 4.2 && < 5
+ hs-source-dirs: src
+
Then nix build
executes fine, but the only file in result
is bin/hello
- no library. The reason I was trying to run nix flake show
was to try to understand what the provided outputs are - but no joy. How would I find that out, and how do I add a library to the outputs?
Overall, I think this flake.nix
could do with a few more explanatory comments and documentation links for newer users like myself.