Skip to content

Commit 725ceb2

Browse files
committed
Port static-stack to static-stack2nix-builder.
Drastically simplifies it. Fix fallout: * Add sqlite override for `persistent-sqlite`. * Override stack release flags that `stack2nix`/`cabal2nix` now add. * Mark ghc822 as supported, as the stack build tests it. * Remove superfluous addition of Cabal to `libraryHaskellDepends`.
1 parent 7609657 commit 725ceb2

File tree

4 files changed

+65
-140
lines changed

4 files changed

+65
-140
lines changed

static-stack/README.md

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,15 @@
22

33
This builds a fully statically linked `stack` executable that should work on any 64-bit Linux distribution.
44

5-
It uses nix's cross-compilation support to build everything, including `ghc`, against the `musl` libc.
5+
It uses nix to build everything, including `ghc`, against the `musl` libc.
66

77
## Building
88

99
```
10-
$(nix-build --no-out-link -A stack2nix-script) /path/to/stack/source
11-
$(nix-build --no-out-link -A build-script)
10+
$(nix-build --no-link -A run-stack2nix-and-static-build-script --argstr stackDir /absolute/path/to/stack/source)
1211
```
1312

14-
We use the `$(nix-build ...)` script approach in order to pin the version of `nix` itself for reproducibility.
13+
We use the `$(nix-build ...)` script approach in order to pin the version of `nix` itself for reproducibility, and because the call to `stack2nix` needs Internet access and thus has to run outside of the nix build sandbox.
1514

1615
## Binary caches for faster building (optional)
1716

static-stack/default.nix

Lines changed: 43 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -1,113 +1,52 @@
1-
{
2-
release ? false,
3-
}:
41
# Builds a static `stack` executable from a stack source dir.
52
#
63
# Usage:
74
#
8-
# $(nix-build --no-out-link -A stack2nix-script) /path/to/stack/source --stack-yaml stack-nightly.yaml && nix-build --no-out-link -A static_stack
9-
#
10-
# We do it this way instead of writing a derivation that
11-
# does that for you because as of writing, `stack2nix` doesn't support
12-
# being run from within a nix build, because it calls `cabal update`.
5+
# $(nix-build --no-link -A run-stack2nix-and-static-build-script --argstr stackDir /absolute/path/to/stack/source)
6+
{
7+
stackDir ? "/absolute/path/to/stack/source",
8+
}:
139
let
14-
pyopenssl-fix-test-buffer-size-overlay = final: previous: {
15-
python36 = previous.python36.override {
16-
packageOverrides = self: super: {
17-
cython = super.cython.overridePythonAttrs (old: rec {
18-
# TODO Cython tests for unknown reason hang with musl. Remove when that's fixed.
19-
# See https://github.com/nh2/static-haskell-nix/issues/6#issuecomment-421852854
20-
doCheck = false;
21-
});
22-
pyopenssl = super.pyopenssl.overridePythonAttrs (old: rec {
23-
patches = [
24-
# TODO Remove when https://github.com/pyca/pyopenssl/commit/b2777a465b669fb647dbac0a92919cb05458707b is available in nixpkgs
25-
(final.fetchpatch {
26-
name = "wantWriteError-test-buffer-size.patch";
27-
url = "https://github.com/pyca/pyopenssl/commit/b2777a465b669fb647dbac0a92919cb05458707b.patch";
28-
sha256 = "0igksnl0cd5cx8f38bfjdriwdrzbw6ciy0hs805s84mprfwhck8d";
29-
})
30-
];
31-
});
32-
};
33-
};
34-
};
35-
36-
normalPkgs = import (fetchTarball https://github.com/nh2/nixpkgs/archive/442912b4f19644311700b43b3b5247c6291d785a.tar.gz) {};
3710

38-
# In `survey` we provide a nixpkgs set with some fixes; import it here.
39-
pkgs = (import ../survey/default.nix {
40-
inherit normalPkgs;
41-
overlays = [ pyopenssl-fix-test-buffer-size-overlay ];
42-
}).pkgs;
11+
upstreamNixpkgs = import ../nixpkgs {};
4312

44-
# TODO Use `pkgs.stack2nix` instead of this once `stack2nix` 0.2 is in `pkgs`
45-
stack2nix_src = pkgs.fetchFromGitHub {
46-
owner = "input-output-hk";
47-
repo = "stack2nix";
48-
rev = "v0.2.1";
49-
sha256 = "1ihcp3mr0s89xmc81f9hxq07jw6pm3lixr5bdamqiin1skpk8q3b";
13+
static-stack2nix-builder = import ../static-stack2nix-builder/default.nix {
14+
cabalPackageName = "stack";
15+
normalPkgs = upstreamNixpkgs;
16+
compiler = "ghc822"; # matching stack.yaml
17+
hackageSnapshot = "2019-05-08T00:00:00Z"; # pins e.g. extra-deps without hashes or revisions
18+
stack2nix-stack-project-dir = stackDir; # where stack.yaml is
19+
# disableOptimization = true; # for compile speed
5020
};
51-
stack2nix = import (stack2nix_src + "/default.nix") {};
52-
53-
# Script that runs `stack2nix` on a given stack source dir.
54-
# Arguments given to the script are given to `stack2nix`.
55-
# Running the script creates file `stack.nix`.
56-
stack2nix-script =
57-
# `stack2nix` requires `cabal` on $PATH.
58-
# We put our nixpkgs's version of `nix` on $PATH for reproducibility.
59-
pkgs.writeScript "stack2nix-build-script.sh" ''
60-
#!/usr/bin/env bash
61-
set -eu -o pipefail
62-
PATH=${pkgs.cabal-install}/bin:${normalPkgs.nix}/bin:$PATH ${stack2nix}/bin/stack2nix -o stack.nix $@
63-
'';
64-
65-
# Apply patch to generated stack2nix output to work around
66-
# 'libyaml' dependency to be named 'yaml'; see
67-
# https://github.com/NixOS/cabal2nix/issues/378
68-
# Note this patch depends on
69-
# https://github.com/commercialhaskell/stack/blob/a2489de02/stack.yaml#L27
70-
# which includes
71-
# https://github.com/snoyberg/yaml/pull/151/commits/ba216731cd5bf4264e9ad95d55616ff1a9edfac5
72-
# This patch doesn't apply and can be removed if either
73-
# * the `stack` version to be compiled has `yaml` older than in the line mentioned above, or
74-
# * the `cabal2nix` version in use has https://github.com/NixOS/cabal2nix/commit/67e3189f fixed
75-
stack2nix-output = pkgs.runCommand "stack.nix-patched" {} ''
76-
cp ${./stack.nix} $out
77-
patch -p1 $out ${./stack-libyaml-dependency-name-cabal2nix-issue-378.patch}
78-
'';
7921

80-
enableCabalFlags = flags: drv: builtins.foldl' (d: flag: pkgs.haskell.lib.enableCabalFlag d flag) drv flags;
81-
setStackFlags = drv:
82-
if release
83-
then enableCabalFlags [ "hide-dependency-versions" "supported-build" ] drv
84-
else drv;
85-
# Builds a static stack executable from a `stack.nix` file generated
86-
# with `stack2nix`.
87-
static_stack = setStackFlags (import ../survey/default.nix {
88-
normalPkgs = pkgs;
89-
normalHaskellPackages = import stack2nix-output {
90-
inherit pkgs;
91-
};
92-
}).haskellPackages.stack;
93-
# TODO check if `overrideCabal super.stack (old: { executableToolDepends = [ pkgs.git ]; })`
94-
# is necessary here now that it's removed from `survey`
95-
96-
# Script that runs `nix-build` to build the final executable.
97-
# We do this to fix the version of `nix` to the one in our nixpkgs
98-
# for reproducibility, as changing nix versions can change the build env.
99-
# Arguments given to the script are given to `nix-build`.
100-
build-script =
101-
pkgs.writeScript "stack-build-script.sh" ''
102-
#!/usr/bin/env bash
103-
set -eu -o pipefail
104-
set -x
105-
${normalPkgs.nix}/bin/nix-build --no-out-link -A static_stack $@
106-
'';
107-
108-
in {
109-
inherit pkgs;
110-
inherit stack2nix-script;
111-
inherit static_stack;
112-
inherit build-script;
113-
}
22+
in
23+
static-stack2nix-builder // {
24+
static_package =
25+
with upstreamNixpkgs.haskell.lib;
26+
overrideCabal
27+
(appendConfigureFlags
28+
static-stack2nix-builder.static_package
29+
[
30+
# Official release flags:
31+
"-fsupported-build"
32+
"-fhide-dependency-versions"
33+
"-f-disable-git-info" # stack2nix turns that on, we turn it off again
34+
]
35+
)
36+
(old: {
37+
# Enabling git info needs these extra deps.
38+
# TODO Make `stack2nix` accept per-package Cabal flags,
39+
# so that `cabal2nix` would automatically add
40+
# the right dependencies for us.
41+
executableHaskellDepends = (old.executableHaskellDepends or []) ++
42+
(with static-stack2nix-builder.haskell-static-nix_output.haskellPackages; [
43+
githash
44+
optparse-simple
45+
]);
46+
# Put `git` on PATH, because `githash` calls it.
47+
preConfigure = ''
48+
export PATH=${upstreamNixpkgs.git}/bin:$PATH
49+
git --version
50+
'';
51+
});
52+
}

static-stack/stack-libyaml-dependency-name-cabal2nix-issue-378.patch

Lines changed: 0 additions & 27 deletions
This file was deleted.

survey/default.nix

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ in
4747

4848
defaultCabalPackageVersionComingWithGhc ?
4949
({
50-
ghc822 = throw "static-haskell-nix: ghc822 wasn't tried yet with the static nix Cabal patch; please try and PR it";
50+
ghc822 = "Cabal_2_2_0_1"; # TODO this is technically incorrect for ghc 8.2.2, should be 2.0.1.0, but nixpkgs doesn't have that
5151
ghc844 = "Cabal_2_2_0_1";
5252
ghc863 = throw "static-haskell-nix: ghc863 is no longer supported, please upgrade";
5353
ghc864 = "Cabal_2_4_1_0"; # TODO this is technically incorrect for ghc 8.6.4, should be 2.4.0.1, but nixpkgs doesn't have that
@@ -413,10 +413,17 @@ let
413413
# here, so we use the `haskellPackagesWithLibsReadyForStaticLinking`
414414
# one instead which has set `Cabal = ...` appropriately.
415415
setupHaskellDepends = patchCabalInPackageList ((old.setupHaskellDepends or []) ++ [fixedCabal]);
416-
# We also need to add the fixed cabal to the normal dependencies,
417-
# for the case that the package itself depends on Cabal; see note
418-
# [Fixed Cabal for Setup.hs->somePackage->Cabal dependencies].
419-
libraryHaskellDepends = patchCabalInPackageList ((old.libraryHaskellDepends or []) ++ [fixedCabal]);
416+
# We don't need to add it to `libraryHaskellDepends` (see note
417+
# [Fixed Cabal for Setup.hs->somePackage->Cabal dependencies])
418+
# here because we already add it to the package set itself
419+
# down in `haskellLibsReadyForStaticLinkingOverlay`.
420+
# In fact, adding it here breaks e.g. the example in
421+
# `static-stack`, because `stack2nix` adds stacks specified
422+
# `Cabal` dependency as `libraryHaskellDepends`
423+
# (which is then patched via `applyPatchesToCabalDrv` in
424+
# `haskellLibsReadyForStaticLinkingOverlay`) and adding
425+
# it here would add a second, different Cabal version to the
426+
# ghc package DB.
420427
})).overrideAttrs (old: {
421428
# Adding the fixed Cabal version to `setupHaskellDepends` is not enough:
422429
# There may already be one in there, in which case GHC picks an
@@ -813,6 +820,13 @@ let
813820
];
814821
}))).override { openblasCompat = final.openblasCompat; };
815822

823+
# TODO Find out why this is needed.
824+
# Without this, the stack in `./static-stack` doesn't link,
825+
# complaining `cannot find -lsqlite3`.
826+
# `persistent-sqlite` should already be using `final.sqlite`,
827+
# but apparently it's not.
828+
persistent-sqlite = super.persistent-sqlite.override { sqlite = final.sqlite; };
829+
816830
# TODO For the below packages, it would be better if we could somehow make all users
817831
# of postgresql-libpq link in openssl via pkgconfig.
818832
postgresql-schema =

0 commit comments

Comments
 (0)