-
-
Notifications
You must be signed in to change notification settings - Fork 115
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[aura] Static builds with stack-haskell-nix
Hi, Colin. I'm finally doing that "look at how magical NixOS is" thing from 6 years ago. The patches are to bodge static-haskell-nix into building with Stackage lts-15.12, which means stack2nix on Stack 2.1 and also means static-haskell-nix on GHC 8.8.3 (and Cabal 3.0.1.0). I'm not sure how much of this is readily upstreamable.
- Loading branch information
Showing
12 changed files
with
39,535 additions
and
8 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
# Nix | ||
/nix/sources.nix linguist-vendored | ||
/nix/sources.json linguist-generated | ||
/nix/*-stack2nix-output.nix linguist-generated |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,131 @@ | ||
{ ... } @ commonArgs: | ||
let common = with common; { | ||
pkgs = import <nixpkgs> { }; | ||
ghc = pkgs.ghc; | ||
let | ||
inherit (builtins) foldl'; | ||
fix = unfix: let self = unfix self; in self; | ||
extends = overlay: unfix: self: | ||
let | ||
super = unfix self; | ||
selfUnmerged = overlay self super; | ||
in super // selfUnmerged; | ||
extendList = foldl' (unfix: overlay: extends overlay unfix); | ||
|
||
commonOverlay.base = common: commonSuper: with common; { | ||
|
||
nixpkgs = <nixpkgs>; | ||
nixpkgsArg = { }; | ||
pkgs = import nixpkgs nixpkgsArg; | ||
sources = import ./sources.nix { }; | ||
|
||
# matching stack.yaml | ||
haskellCompiler = "ghc883"; # lts-15.13 (ghc-8.8.3) | ||
# pins e.g. extra-deps without hashes or revisions | ||
hackageSnapshot = "2020-05-19T00:00:00Z"; | ||
|
||
haskellPackages = pkgs.haskell.packages.${haskellCompiler}; | ||
ghc = haskellPackages.ghc; | ||
|
||
# stack build / stack run | ||
stackProject = import ./stack.nix { inherit common; }; | ||
} // commonArgs; in common | ||
# "$(nix-build --no-out-link ./nix -A staticProject.fullBuildScript)" | ||
staticProject = import ./static.nix { inherit common; }; | ||
|
||
static-haskell-nix = pkgs.applyPatches { | ||
name = "static-haskell-nix-src"; | ||
src = sources.static-haskell-nix.outPath; | ||
patches = [ | ||
./static-haskell-nix-fixed_stack2nix-override.patch | ||
./static-haskell-nix-newer-cabal-versions.patch | ||
]; | ||
}; | ||
# lts-15+ requires Stack >= 2.0 | ||
# https://www.stackage.org/blog/2020/02/discontinuing-legacy-snapshots | ||
# You can set `haskellPackages` if you like, | ||
# but be careful with the compiler you move to (currently "ghc865"). | ||
stack2nix = import (pkgs.applyPatches { | ||
name = "stack2nix-src"; | ||
src = sources.stack2nix; | ||
patches = [ | ||
# Make GHC base libraries dependent on GHC version. | ||
# https://github.com/input-output-hk/stack2nix/pull/172 | ||
./stack2nix-per-ghc-base-packages.patch | ||
# (pkgs.fetchpatch { | ||
# url = "https://github.com/input-output-hk/stack2nix/commit/c009e33af30c76b8fe94388382d816079fb5ac4e.patch"; | ||
# sha256 = "0x44lcmzywvzhymch0hhg4j1r3592v51xw552kawm2zd0cfp8qhz"; | ||
# }) | ||
]; | ||
postPatch = '' | ||
cp ${sources.ghc-utils}/library-versions/pkg_versions.txt ./pkg_versions.txt | ||
sed -i \ | ||
-e '1s/ }:/, haskellPackages ? null } @ args:/' \ | ||
-e 's/\(import .\/stack2nix.nix\) { inherit pkgs; }/\1 args/' \ | ||
./default.nix | ||
sed ./pkg_versions.txt \ | ||
-e '/^\(#\|$\)/d; s/\(\S\+\)\/\S\+/"\1",/g; s/^\(\S\+\)\s*/ , ("\1", [/; s/,\?$/])/' | sed '1s/^ ,/ghcBaseLibsMap = M.fromListWith (++)\n [/; $s/$/\n ]/' \ | ||
>> ./src/Stack2nix/External/Stack.hs | ||
''; | ||
}) { inherit pkgs; }; | ||
|
||
}; | ||
|
||
commonOverlay.pin = common: commonSuper: with common; { | ||
|
||
# If pinned, you'll probably want the static-haskell-nix binary subsituter. | ||
# substituter: https://static-haskell-nix.cachix.org | ||
# trusted-public-key: 1:Q17HawmAwaM1/BfIxaEDKAxwTOyRVhPG5Ji9K3+FvUU= | ||
pinned = true; | ||
|
||
nixpkgs = if pinned then sources.nixpkgs else commonSuper.nixpkgs; | ||
nixpkgsArg = if pinned then { | ||
config = { }; | ||
overlays = [ ]; | ||
} else commonSuper.nixpkgsArg; | ||
|
||
}; | ||
|
||
# By patching the Nixpkgs source, patches won't be dropped due to | ||
# reevaluations by a `pkgs.path` (not reusing the passed `pkgs` value). | ||
# (This isn't as much of an issue for e.g. normal `<nixpkgs>` due to ambient | ||
# mutable configuration, like `~/.config/nixpkgs/config.nix`.) | ||
commonOverlay.patchNixpkgs = common: commonSuper: with common; { | ||
|
||
nixpkgsUnpatched = commonSuper.nixpkgs; | ||
pkgsUnpatched = import nixpkgsUnpatched nixpkgsArg; | ||
|
||
nixpkgs = pkgsUnpatched.applyPatches { | ||
name = "nixpkgs"; | ||
src = nixpkgsUnpatched; | ||
patches = let | ||
# configure.ac: make cross-compiler detection stricter | ||
# (broken since GHC 8.2.1: Fix configure detection.) | ||
# https://gitlab.haskell.org/ghc/ghc/commit/18f06878ed5d8cb0cf366a876f2bfea29647e5f0 | ||
# https://gitlab.haskell.org/ghc/ghc/merge_requests/2234 | ||
# https://gitlab.haskell.org/ghc/ghc/commit/4cbd5b47a00a29b7835710f1b91bb93ac8e3f790 | ||
nixpkgs-ghc-2234-cross-detect = [ | ||
./nixpkgs-ghc-2234-cross-detect.patch | ||
]; | ||
|
||
# ghc: do not use ld.gold with musl libc #84670 | ||
# https://github.com/NixOS/nixpkgs/pull/84741 | ||
# GHC does not compile on pkgsMusl after the ld.gold change | ||
# https://github.com/NixOS/nixpkgs/issues/84670 | ||
nixpkgs-84670-ghc-musl-no-ld-gold = [ | ||
(pkgsUnpatched.fetchpatch { | ||
url = "https://github.com/NixOS/nixpkgs/commit/acfccf7f5ba83ce4ec279ce4416e5de5edca2fb7.patch"; | ||
sha256 = "0iv2mbw80qjr7d7gcpv0n7j7qdpn2vxky4zimw6qf9w409pbil2f"; | ||
}) | ||
]; | ||
in | ||
# nixpkgs-ghc-2234-cross-detect ++ | ||
nixpkgs-84670-ghc-musl-no-ld-gold ++ | ||
[ ]; | ||
}; | ||
|
||
}; | ||
|
||
in { ... } @ commonArgs: fix (extendList (common: commonArgs) [ | ||
commonOverlay.base | ||
commonOverlay.pin | ||
commonOverlay.patchNixpkgs | ||
(common: commonSuper: commonArgs) | ||
]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
--- a/pkgs/development/compilers/ghc/8.8.3.nix | ||
+++ b/pkgs/development/compilers/ghc/8.8.3.nix | ||
@@ -2,7 +2,7 @@ | ||
|
||
# build-tools | ||
, bootPkgs | ||
-, autoconf, automake, coreutils, fetchurl, perl, python3, m4, sphinx | ||
+, autoconf, automake, coreutils, fetchpatch, fetchurl, perl, python3, m4, sphinx | ||
, bash | ||
|
||
, libiconv ? null, ncurses | ||
@@ -100,6 +100,11 @@ | ||
|
||
outputs = [ "out" "doc" ]; | ||
|
||
+ patches = [ (fetchpatch { | ||
+ url = "https://gitlab.haskell.org/ghc/ghc/commit/4cbd5b47a00a29b7835710f1b91bb93ac8e3f790.patch"; | ||
+ sha256 = "09z0l2yy41b7wpp70f9xwfyxmar8ics48hm34892aqvrk715h8jk"; | ||
+ }) ]; | ||
+ | ||
postPatch = "patchShebangs ."; | ||
|
||
# GHC is a bit confused on its cross terminology. | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,138 @@ | ||
# This file has been generated by Niv. | ||
|
||
let | ||
|
||
# | ||
# The fetchers. fetch_<type> fetches specs of type <type>. | ||
# | ||
|
||
fetch_file = pkgs: spec: | ||
if spec.builtin or true then | ||
builtins_fetchurl { inherit (spec) url sha256; } | ||
else | ||
pkgs.fetchurl { inherit (spec) url sha256; }; | ||
|
||
fetch_tarball = pkgs: name: spec: | ||
let | ||
ok = str: ! builtins.isNull (builtins.match "[a-zA-Z0-9+-._?=]" str); | ||
# sanitize the name, though nix will still fail if name starts with period | ||
name' = stringAsChars (x: if ! ok x then "-" else x) "${name}-src"; | ||
in | ||
if spec.builtin or true then | ||
builtins_fetchTarball { name = name'; inherit (spec) url sha256; } | ||
else | ||
pkgs.fetchzip { name = name'; inherit (spec) url sha256; }; | ||
|
||
fetch_git = spec: | ||
builtins.fetchGit { url = spec.repo; inherit (spec) rev ref; }; | ||
|
||
fetch_local = spec: spec.path; | ||
|
||
fetch_builtin-tarball = name: throw | ||
''[${name}] The niv type "builtin-tarball" is deprecated. You should instead use `builtin = true`. | ||
$ niv modify ${name} -a type=tarball -a builtin=true''; | ||
|
||
fetch_builtin-url = name: throw | ||
''[${name}] The niv type "builtin-url" will soon be deprecated. You should instead use `builtin = true`. | ||
$ niv modify ${name} -a type=file -a builtin=true''; | ||
|
||
# | ||
# Various helpers | ||
# | ||
|
||
# The set of packages used when specs are fetched using non-builtins. | ||
mkPkgs = sources: | ||
let | ||
sourcesNixpkgs = | ||
import (builtins_fetchTarball { inherit (sources.nixpkgs) url sha256; }) {}; | ||
hasNixpkgsPath = builtins.any (x: x.prefix == "nixpkgs") builtins.nixPath; | ||
hasThisAsNixpkgsPath = <nixpkgs> == ./.; | ||
in | ||
if builtins.hasAttr "nixpkgs" sources | ||
then sourcesNixpkgs | ||
else if hasNixpkgsPath && ! hasThisAsNixpkgsPath then | ||
import <nixpkgs> {} | ||
else | ||
abort | ||
'' | ||
Please specify either <nixpkgs> (through -I or NIX_PATH=nixpkgs=...) or | ||
add a package called "nixpkgs" to your sources.json. | ||
''; | ||
|
||
# The actual fetching function. | ||
fetch = pkgs: name: spec: | ||
|
||
if ! builtins.hasAttr "type" spec then | ||
abort "ERROR: niv spec ${name} does not have a 'type' attribute" | ||
else if spec.type == "file" then fetch_file pkgs spec | ||
else if spec.type == "tarball" then fetch_tarball pkgs name spec | ||
else if spec.type == "git" then fetch_git spec | ||
else if spec.type == "local" then fetch_local spec | ||
else if spec.type == "builtin-tarball" then fetch_builtin-tarball name | ||
else if spec.type == "builtin-url" then fetch_builtin-url name | ||
else | ||
abort "ERROR: niv spec ${name} has unknown type ${builtins.toJSON spec.type}"; | ||
|
||
# Ports of functions for older nix versions | ||
|
||
# a Nix version of mapAttrs if the built-in doesn't exist | ||
mapAttrs = builtins.mapAttrs or ( | ||
f: set: with builtins; | ||
listToAttrs (map (attr: { name = attr; value = f attr set.${attr}; }) (attrNames set)) | ||
); | ||
|
||
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/lists.nix#L295 | ||
range = first: last: if first > last then [] else builtins.genList (n: first + n) (last - first + 1); | ||
|
||
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L257 | ||
stringToCharacters = s: map (p: builtins.substring p 1 s) (range 0 (builtins.stringLength s - 1)); | ||
|
||
# https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L269 | ||
stringAsChars = f: s: concatStrings (map f (stringToCharacters s)); | ||
concatStrings = builtins.concatStringsSep ""; | ||
|
||
# fetchTarball version that is compatible between all the versions of Nix | ||
builtins_fetchTarball = { url, name, sha256 }@attrs: | ||
let | ||
inherit (builtins) lessThan nixVersion fetchTarball; | ||
in | ||
if lessThan nixVersion "1.12" then | ||
fetchTarball { inherit name url; } | ||
else | ||
fetchTarball attrs; | ||
|
||
# fetchurl version that is compatible between all the versions of Nix | ||
builtins_fetchurl = { url, sha256 }@attrs: | ||
let | ||
inherit (builtins) lessThan nixVersion fetchurl; | ||
in | ||
if lessThan nixVersion "1.12" then | ||
fetchurl { inherit url; } | ||
else | ||
fetchurl attrs; | ||
|
||
# Create the final "sources" from the config | ||
mkSources = config: | ||
mapAttrs ( | ||
name: spec: | ||
if builtins.hasAttr "outPath" spec | ||
then abort | ||
"The values in sources.json should not have an 'outPath' attribute" | ||
else | ||
spec // { outPath = fetch config.pkgs name spec; } | ||
) config.sources; | ||
|
||
# The "config" used by the fetchers | ||
mkConfig = | ||
{ sourcesFile ? ./sources.json | ||
, sources ? builtins.fromJSON (builtins.readFile sourcesFile) | ||
, pkgs ? mkPkgs sources | ||
}: rec { | ||
# The sources, i.e. the attribute set of spec name to spec | ||
inherit sources; | ||
|
||
# The "pkgs" (evaluated nixpkgs) to use for e.g. non-builtin fetchers | ||
inherit pkgs; | ||
}; | ||
in | ||
mkSources (mkConfig {}) // { __functor = _: settings: mkSources (mkConfig settings); } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.