Skip to content

Commit

Permalink
Fix stack integration, use version of stack2nix that supports Stack 2.
Browse files Browse the repository at this point in the history
This uses @qrilka's work from nh2/stack2nix#1,
now moved to nh2/stack2nix#2.

Unfortunately, this introduces a backwards incompatibility for stack users:

The `stack2nix-script` nix expression now needs to be passed `inherit compiler`,
to satisfy stack complaining if there's no matching GHC on PATH
(even though we don't use it).

I haven't found a way around that yet.

Example change that users need to make in their `default.nix` for building
stack projects statically:

       stack2nix-script = import "${static-haskell-nix}/static-stack2nix-builder/stack2nix-script.nix" {
         inherit pkgs;
    +    inherit compiler;
         stack-project-dir = toString ./.; # where stack.yaml is
         hackageSnapshot = "2021-07-11T00:00:00Z"; # pins e.g. extra-deps without hashes or revisions
       };
  • Loading branch information
nh2 committed Jul 20, 2021
1 parent 7a3992b commit 1f557c2
Show file tree
Hide file tree
Showing 10 changed files with 35 additions and 55 deletions.
7 changes: 1 addition & 6 deletions .buildkite/pipeline.yml
Original file line number Diff line number Diff line change
Expand Up @@ -54,11 +54,6 @@ steps:
cd static-stack/
mkdir -p static-stack-test-dir
curl -L https://github.com/commercialhaskell/stack/archive/v2.1.3.tar.gz | tar -xz -C static-stack-test-dir
# Use lts-12 because ghc822 is no longer in nixpkgs
cp static-stack-test-dir/stack-*/stack-lts-12.yaml static-stack-test-dir/stack-*/stack.yaml
echo "Overriding point release of unix-compat, see https://github.com/nh2/static-haskell-nix/issues/79"
perl -pi -e 's/^packages:/packages:\n- unix-compat-0.5.2\@rev:0/g' static-stack-test-dir/stack-*/snapshot-lts-12.yaml
curl -L https://github.com/commercialhaskell/stack/archive/v2.7.1.tar.gz | tar -xz -C static-stack-test-dir
$(nix-build --no-link -A fullBuildScript --argstr stackDir $PWD/static-stack-test-dir/stack-*)
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -116,5 +116,7 @@ The [`static-stack`](./static-stack) directory shows how Stack itself can be bui
then `/nix/store/dax3wjbjfrcwj6r3mafxj5fx6wcg5zbp-stack-2.3.0.1` is your final output _store path_ whose `/bin` directory contains your static executable.
* I get `stack2nix: user error (No such package mypackage-1.2.3 in the cabal database. Did you run cabal update?)`.
* You most likely have to bump the date like `hackageSnapshot = "2019-05-08T00:00:00Z";` to a newer date (past the time that package-version was added to Hackage).
* Can I build Stack projects with resolvers that are too old to be supported by Stack >= 2?
* No. For that you need need to use an old `static-haskell-nix` version: The one before [this PR](https://github.com/nh2/static-haskell-nix/pull/98) was merged.
* I get some other error. Can I just file an issue and have you help me with it?
* Yes. If possible (especially if your project is open source), please push some code so that your issue can be easily reproduced.
2 changes: 1 addition & 1 deletion nixpkgs.nix
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ if builtins.getEnv "STATIC_HASKELL_NIX_CI_NIXPKGS_UNSTABLE_BUILD" == "1"
if builtins.pathExists ./nixpkgs/pkgs
then import ./nixpkgs {}
# Pinned nixpkgs version; should be kept up-to-date with our submodule.
else import (fetchTarball https://github.com/NixOS/nixpkgs/archive/0c960262d159d3a884dadc3d4e4b131557dad116.tar.gz) {}
else import (fetchTarball https://github.com/nh2/nixpkgs/archive/8d536f36256d30d8fa47b24caafb1af6405889f3.tar.gz) {}
10 changes: 0 additions & 10 deletions static-stack/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,6 @@ If you get an error such as:
then update the `hackageSnapshot` date in `default.nix` to a date that includes the package and version.

### Temporarily: Use `stack-lts-12.yaml`

See #81: Stack's main `stack.yaml` uses GHC 8.2.2, which is no longer in recent `nixpkgs`.

If you get an error mentioning `error: attribute 'ghc822' in selection path 'haskell.compiler.ghc822' not found`, then build stack the same way [as our CI does it](https://github.com/nh2/static-haskell-nix/blob/38ef5a4e00b5f6fb421014829320d85899483874/.buildkite/pipeline.yml#L50-L64).

Alternatively you can use an older version of `static-haskell-nix` that pins an older version of `nixpkgs` that still has `ghc822`.

This issue will likely go away very soon given that [stack is as-of-writing upgrading `stack.yaml` to a newer LTS](https://github.com/commercialhaskell/stack/pull/5162).

## Binary caches for faster building (optional)

You can use the caches described in the [top-level README](../README.md#binary-caches-for-faster-building-optional) for faster building.
Expand Down
7 changes: 4 additions & 3 deletions static-stack/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,15 @@
}:
let
cabalPackageName = "stack";
compiler = "ghc844"; # matching stack-lts-12.yaml
compiler = "ghc8104"; # matching stack-lts-12.yaml

pkgs = import ../nixpkgs {};

stack2nix-script = import ../static-stack2nix-builder/stack2nix-script.nix {
pkgs = pkgs;
inherit pkgs;
inherit compiler;
stack-project-dir = stackDir; # where stack.yaml is
hackageSnapshot = "2020-02-08T00:00:00Z"; # pins e.g. extra-deps without hashes or revisions
hackageSnapshot = "2021-07-12T00:00:00Z"; # pins e.g. extra-deps without hashes or revisions
};

static-stack2nix-builder = import ../static-stack2nix-builder/default.nix {
Expand Down
5 changes: 3 additions & 2 deletions static-stack2nix-builder-example/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
}:
let
cabalPackageName = "example-project";
compiler = "ghc865"; # matching stack.yaml
compiler = "ghc8104"; # matching stack.yaml

# Pin static-haskell-nix version.
static-haskell-nix =
Expand All @@ -23,8 +23,9 @@ let

stack2nix-script = import "${static-haskell-nix}/static-stack2nix-builder/stack2nix-script.nix" {
inherit pkgs;
inherit compiler;
stack-project-dir = toString ./.; # where stack.yaml is
hackageSnapshot = "2019-10-08T00:00:00Z"; # pins e.g. extra-deps without hashes or revisions
hackageSnapshot = "2021-07-11T00:00:00Z"; # pins e.g. extra-deps without hashes or revisions
};

static-stack2nix-builder = import "${static-haskell-nix}/static-stack2nix-builder/default.nix" {
Expand Down
2 changes: 1 addition & 1 deletion static-stack2nix-builder-example/stack.yaml
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
resolver: lts-14.7
resolver: lts-18.2
packages:
- .
6 changes: 3 additions & 3 deletions static-stack2nix-builder/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,19 @@
# The name of the cabal package to build, e.g. "pandoc".
cabalPackageName ? "myproject",

# Compiler name in nixpkgs, e.g. "ghc864".
# Compiler name in nixpkgs, e.g. "ghc8104".
# Must match the one in the `resolver` in `stack.yaml`.
# If you get this wrong, you'll likely get an error like
# <command line>: cannot satisfy -package-id Cabal-2.4.1.0-ALhzvdqe44A7vLWPOxSupv
# TODO: Make `stack2nix` tell us that.
compiler ? "ghc864",
compiler ? "ghc8104",

# Path to `stack2nix` output that shall be used as Haskell packages.
# You should usually give this the store path that `stack2nix-script` outputs.
stack2nix-output-path,

# Pin nixpkgs version.
normalPkgs ? import (fetchTarball https://github.com/NixOS/nixpkgs/archive/88ae8f7d55efa457c95187011eb410d097108445.tar.gz) {},
normalPkgs ? import (fetchTarball https://github.com/nh2/nixpkgs/archive/8d536f36256d30d8fa47b24caafb1af6405889f3.tar.gz) {},

# Use `integer-simple` instead of `integer-gmp` to avoid linking in
# this LGPL dependency statically.
Expand Down
47 changes: 19 additions & 28 deletions static-stack2nix-builder/stack2nix-script.nix
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,18 @@
# nixpkgs to use.
pkgs,

# ghc to use; only because without a GHC on path, stack complains:
# stack2nix: No compiler found, expected minor version match with ghc-8.10.4 (x86_64) (based on resolver setting ...
# This happens even when using the Stack API (as stack2nix does),
# and stack2nix doen't currently accept or set the `--system-ghc`
# flag to skip the check (maybe it should to eschew this option;
# I suspect our operation here never uses GHC).
# TODO: This shouldn't be necessary since `stack2nix` commit
# Set `--system-ghc` via stack API.
# But somehow stack2nix still complains about it;
# perhaps we didn't use the Stack API correctly.
compiler,

# Path to directory containing `stack.yaml`.
stack-project-dir,

Expand Down Expand Up @@ -47,37 +59,16 @@
"${pkgs.cabal-install}/bin" # `cabal`
"${pkgs.nix}/bin" # various `nix-*` commands
"${pkgs.wget}/bin" # `wget`
"${pkgs.haskell.compiler.${compiler}}/bin" # `ghc` version matching target stack.yaml
];

fixed_stack2nix =
let
# stack2nix isn't compatible with Stack >= 2.0, see
# https://github.com/input-output-hk/stack2nix/issues/168.
# Current versions of nixpkgs master have Stack >= 2.0, see
# https://github.com/NixOS/nixpkgs/issues/63691.
# We thus fetch the `stack2nix` binary from an older nixpkgs version
# that doesn't have Stack >= 2.0.
# This means that `static-stack2nix-builder` may not work on `stack.yaml`
# files that aren't compatible with Stack < 2.0.
stack2nix_pkgs = import (fetchTarball https://github.com/NixOS/nixpkgs/archive/e36f91fa86109fa93cac2516a9365af57233a3a6.tar.gz) {};
in
# Some older stack2nix versions have fundamental problems that prevent
# stack2nix from running correctly. Fix them here, until these old versions
# are faded out of current nixpkgs. Especially:
# * "Make sure output is written in UTF-8."
# https://github.com/input-output-hk/stack2nix/commit/cb05818ef8b58899f15641f50cb04e5473b4f9b0
# * "Make GHC base libraries dependent on GHC version."
# https://github.com/input-output-hk/stack2nix/pull/172/commits
#
# Versions < 0.2.4 aren't supported, force-upgrade them to 0.2.4.
if stack2nix_pkgs.lib.versionOlder stack2nix_pkgs.stack2nix.version "0.2.4"
then stack2nix_pkgs.haskellPackages.callCabal2nix "stack2nix" (stack2nix_pkgs.fetchFromGitHub {
owner = "nh2";
repo = "stack2nix";
rev = "c009e33af30c76b8fe94388382d816079fb5ac4e";
sha256 = "0x0hjzjlx1a0pyjd8aalk3ajwcymsb2qd65n2sqdhpy9bdsz8vxl";
}) {}
else stack2nix_pkgs.stack2nix;
pkgs.haskellPackages.callCabal2nix "stack2nix" (pkgs.fetchFromGitHub {
owner = "nh2";
repo = "stack2nix";
rev = "c20097d4edf82256484a733544579d4b5e0f2808";
sha256 = "1lpwc20q62z9a9fpksd9q10x1jz8l29psx4dqsff759srj4chy9p";
}) {};
in
pkgs.writeShellScript "stack2nix-build-script.sh" ''
set -eu -o pipefail
Expand Down
2 changes: 1 addition & 1 deletion survey/default.nix
Original file line number Diff line number Diff line change
Expand Up @@ -1074,7 +1074,7 @@ let
# servant-server
# Some getting: *** abort because of serious configure-time warning from Cabal (multiple different package versions in project)
# stack2nix
Cabal =
Cabal = if !areCabalPatchesRequired then super.Cabal else # no patches needed -> don't even try to access any attributes
if approach == "pkgsMusl"
then ( # Example package where this matters: `focuslist`
# See note [When Cabal is `null` in a package set].
Expand Down

0 comments on commit 1f557c2

Please sign in to comment.