Skip to content

Commit 1adafa0

Browse files
authored
Build a completely static Dhall executable in CI (#517)
This adds a new `dhall-static` target that builds a fully static `dhall` executable that can be run on any Linux machine (i.e. it is a relocatable executable that is completely dependency free). That in turns implies that even though it is built with Nix it doesn't require that the user installs Nix to run it (i.e. no dependency on the `/nix/store` or a Nix installer). Just copy the standalone executable to any Linux machine and it's good to go. This based on the following work of @nh2: * NixOS/nixpkgs#43795 * dhall-lang/dhall-lang#192 (comment) This also bumps the version of `nixpkgs` used for the normal (non-static) Dhall build to be the closest revision on `nixpkgs` `master` as the one used by @nh2 in his work. Once that work is merged into `nixpkgs` `master` then both builds can use the same revision from `nixpkgs` `master`.
1 parent 99db7f7 commit 1adafa0

File tree

3 files changed

+156
-22
lines changed

3 files changed

+156
-22
lines changed

default.nix

Lines changed: 150 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,180 @@
11
let
22
fetchNixpkgs = import ./nix/fetchNixpkgs.nix;
33

4-
nixpkgs = fetchNixpkgs {
5-
rev = "804060ff9a79ceb0925fe9ef79ddbf564a225d47";
6-
7-
sha256 = "01pb6p07xawi60kshsxxq1bzn8a0y4s5jjqvhkwps4f5xjmmwav3";
8-
9-
outputSha256 = "0ga345hgw6v2kzyhvf5kw96hf60mx5pbd9c4qj5q4nan4lr7nkxn";
10-
};
11-
124
readDirectory = import ./nix/readDirectory.nix;
135

14-
config = {
15-
packageOverrides = pkgs: {
16-
haskellPackages = pkgs.haskellPackages.override {
6+
overlayShared = pkgsNew: pkgsOld: {
7+
haskellPackages = pkgsOld.haskellPackages.override (old: {
178
overrides =
189
let
19-
manualOverrides =
10+
extension =
2011
haskellPackagesNew: haskellPackagesOld: {
2112
dhall =
22-
pkgs.haskell.lib.failOnAllWarnings
23-
(pkgs.haskell.lib.justStaticExecutables
13+
pkgsNew.haskell.lib.failOnAllWarnings
14+
(pkgsNew.haskell.lib.overrideCabal
2415
haskellPackagesOld.dhall
16+
(old: {
17+
src =
18+
let
19+
predicate = path: type:
20+
let
21+
base = baseNameOf path;
22+
23+
in
24+
!( pkgsNew.lib.hasSuffix ".nix" base
25+
&& base == "dist"
26+
&& base == "result"
27+
);
28+
29+
in
30+
builtins.filterSource
31+
predicate
32+
old.src;
33+
}
34+
)
2535
);
2636

27-
prettyprinter =
28-
pkgs.haskell.lib.dontCheck haskellPackagesOld.prettyprinter;
37+
prettyprinter =
38+
pkgsNew.haskell.lib.dontCheck
39+
haskellPackagesOld.prettyprinter;
2940
};
3041

3142
in
32-
pkgs.lib.composeExtensions (readDirectory ./nix) manualOverrides;
43+
pkgsNew.lib.fold
44+
pkgsNew.lib.composeExtensions
45+
(old.overrides or (_: _: {}))
46+
[ (readDirectory ./nix)
47+
48+
extension
49+
];
50+
}
51+
);
52+
};
53+
54+
nixpkgs = fetchNixpkgs {
55+
rev = "2c07921cff84dfb0b9e0f6c2d10ee2bfee6a85ac";
56+
57+
sha256 = "09cfdbrzy3wfpqd3nkahv0jqfynpxy4kpcxq0gab0pq9a8bia6sg";
58+
59+
outputSha256 = "1sxh54zxqy54vrak203qci4128z9mxnzfr5bb5pl6xdrdkcdpqrn";
60+
};
61+
62+
pkgs = import nixpkgs { config = {}; overlays = [ overlayShared ]; };
63+
64+
overlayStaticLinux = pkgsNew: pkgsOld: {
65+
cabal_patched_src = pkgsNew.fetchFromGitHub {
66+
owner = "nh2";
67+
repo = "cabal";
68+
rev = "748f07b50724f2618798d200894f387020afc300";
69+
sha256 = "1k559m291f6spip50rly5z9rbxhfgzxvaz64cx4jqpxgfhbh2gfs";
70+
};
71+
72+
Cabal_patched_Cabal_subdir = pkgsNew.stdenv.mkDerivation {
73+
name = "cabal-dedupe-src";
74+
buildCommand = ''
75+
cp -rv ${pkgsNew.cabal_patched_src}/Cabal/ $out
76+
'';
77+
};
78+
79+
haskell = pkgsOld.haskell // {
80+
lib = pkgsOld.haskell.lib // {
81+
useFixedCabal = drv: pkgsNew.haskell.lib.overrideCabal drv (old: {
82+
setupHaskellDepends =
83+
(old.setupHaskellDepends or []) ++ [
84+
pkgsNew.haskellPackages.Cabal_patched
85+
];
86+
87+
libraryHaskellDepends =
88+
(old.libraryHaskellDepends or []) ++ [
89+
pkgsNew.haskellPackages.Cabal_patched
90+
];
91+
}
92+
);
93+
94+
statify = drv:
95+
pkgsNew.lib.foldl pkgsNew.haskell.lib.appendConfigureFlag
96+
(pkgsNew.haskell.lib.disableLibraryProfiling
97+
(pkgsNew.haskell.lib.disableSharedExecutables
98+
(pkgsNew.haskell.lib.useFixedCabal
99+
(pkgsNew.haskell.lib.justStaticExecutables drv)
100+
)
101+
)
102+
)
103+
[ "--enable-executable-static"
104+
"--extra-lib-dirs=${pkgsNew.gmp6.override { withStatic = true; }}/lib"
105+
"--extra-lib-dirs=${pkgsNew.zlib.static}/lib"
106+
"--extra-lib-dirs=${pkgsNew.ncurses.override { enableStatic = true; }}/lib"
107+
];
33108
};
34109
};
110+
111+
haskellPackages = pkgsOld.haskellPackages.override (old: {
112+
overrides =
113+
let
114+
extension =
115+
haskellPackagesNew: haskellPackagesOld: {
116+
Cabal_patched =
117+
pkgsNew.haskellPackages.callCabal2nix
118+
"Cabal"
119+
pkgsNew.Cabal_patched_Cabal_subdir
120+
{ };
121+
122+
dhall = pkgsNew.haskell.lib.statify haskellPackagesOld.dhall;
123+
};
124+
125+
in
126+
pkgsNew.lib.composeExtensions
127+
(old.overrides or (_: _: {}))
128+
extension;
129+
}
130+
);
35131
};
36132

37-
pkgs =
38-
import nixpkgs { inherit config; };
133+
nixpkgsStaticLinux = fetchNixpkgs {
134+
owner = "nh2";
135+
136+
rev = "925aac04f4ca58aceb83beef18cb7dae0715421b";
137+
138+
sha256 = "0zkvqzzyf5c742zcl1sqc8009dr6fr1fblz53v8gfl63hzqwj0x4";
139+
140+
outputSha256 = "1zr8lscjl2a5cz61f0ibyx55a94v8yyp6sjzjl2gkqjrjbg99abx";
141+
};
142+
143+
pkgsStaticLinux = import nixpkgsStaticLinux {
144+
config = {};
145+
overlays = [ overlayShared overlayStaticLinux ];
146+
system = "x86_64-linux";
147+
};
39148

40149
# Derivation that trivially depends on the current directory so that Hydra's
41150
# pull request builder always posts a GitHub status on each revision
42151
pwd = pkgs.runCommand "pwd" { here = ./.; } "touch $out";
43152

44153
in
45-
{ inherit pwd;
154+
rec {
155+
inherit pwd;
156+
157+
tarball =
158+
pkgsStaticLinux.releaseTools.binaryTarball rec {
159+
src = pkgsStaticLinux.pkgsMusl.haskellPackages.dhall;
160+
161+
installPhase = ''
162+
releaseName=${src.name}
163+
${pkgsStaticLinux.coreutils}/bin/install -D "$src/bin/dhall" "$TMPDIR/inst/bin/dhall"
164+
'';
165+
};
46166

47167
inherit (pkgs.haskellPackages) dhall;
48168

169+
all = pkgs.releaseTools.aggregate
170+
{ name = "dhall";
171+
172+
constituents = [
173+
dhall
174+
tarball
175+
pwd
176+
];
177+
};
178+
49179
shell = (pkgs.haskell.lib.doBenchmark pkgs.haskellPackages.dhall).env;
50180
}

nix/fetchNixpkgs.nix

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
{ rev # The Git revision of nixpkgs to fetch
2+
, owner ? "NixOS"
23
, sha256 # The SHA256 of the downloaded data
34
, outputSha256 ? null # The SHA256 fixed-output hash
45
, system ? builtins.currentSystem # This is overridable if necessary
@@ -17,7 +18,7 @@ then (
1718
else (
1819
(rec {
1920
tarball = import <nix/fetchurl.nix> {
20-
url = "https://github.com/NixOS/nixpkgs/archive/${rev}.tar.gz";
21+
url = "https://github.com/${owner}/nixpkgs/archive/${rev}.tar.gz";
2122
inherit sha256;
2223
};
2324

release.nix

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,7 @@ let
22
default = (import ./default.nix);
33

44
in
5-
{ inherit (default) pwd dhall; }
5+
{ dhall = default.all;
6+
7+
inherit (default) tarball;
8+
}

0 commit comments

Comments
 (0)