-
Notifications
You must be signed in to change notification settings - Fork 244
/
Copy pathsetup-builder.nix
134 lines (122 loc) · 4.91 KB
/
setup-builder.nix
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
{ pkgs, stdenv, lib, buildPackages, haskellLib, ghc, nonReinstallablePkgs, hsPkgs, makeSetupConfigFiles }@defaults:
let self =
{ component, package, name, src, enableDWARF ? false, flags ? {}, revision ? null, patches ? [], defaultSetupSrc
, preUnpack ? component.preUnpack, postUnpack ? component.postUnpack
, prePatch ? component.prePatch, postPatch ? component.postPatch
, preBuild ? component.preBuild , postBuild ? component.postBuild
, preInstall ? component.preInstall , postInstall ? component.postInstall
, cleanSrc ? haskellLib.cleanCabalComponent package component "setup" src
, nonReinstallablePkgs ? defaults.nonReinstallablePkgs
, smallAddressSpace ? false
}@drvArgs:
let
ghc = (if enableDWARF then (x: x.dwarf) else (x: x)) (
(if smallAddressSpace then (x: x.smallAddressSpace) else (x: x)) defaults.ghc);
cleanSrc' = haskellLib.rootAndSubDir cleanSrc;
fullName = "${name}-setup";
configFiles = makeSetupConfigFiles {
inherit (package) identifier;
inherit fullName flags component enableDWARF nonReinstallablePkgs;
};
hooks = haskellLib.optionalHooks {
prePatch =
# If the package is in a sub directory `cd` there first.
# In some cases the `cleanSrc.subDir` will be empty and the `.cabal`
# file will be in the root of `src` (`cleanSrc.root`). This
# will happen when:
# * the .cabal file is in the projects `src.origSrc or src`
# * the package src was overridden with a value that does not
# include an `origSubDir`
(lib.optionalString (cleanSrc'.subDir != "") ''
cd ${lib.removePrefix "/" cleanSrc'.subDir}
''
) + lib.optionalString (prePatch != null) "\n${prePatch}";
inherit
preUnpack postUnpack
postPatch
preBuild postBuild
preInstall postInstall
;
};
# the build-tools version might be depending on the version of the package, similarly to patches
executableToolDepends =
let inherit (component) pkgconfig build-tools; in
(lib.concatMap (c: if c.isHaskell or false
then builtins.attrValues (c.components.exes or {})
else [c])
(builtins.filter (x: !(isNull x))
(map
(p: if builtins.isFunction p
then p { inherit (package.identifier) version; inherit revision; }
else p) build-tools))) ++
lib.optional (pkgconfig != []) buildPackages.cabalPkgConfigWrapper;
drv =
stdenv.mkDerivation ({
name = "${ghc.targetPrefix}${fullName}";
src = cleanSrc'.root;
buildInputs = component.libs
++ component.frameworks
++ builtins.concatLists component.pkgconfig
++ configFiles.libDeps
++ [ghc]; # Needs to be a build input so that the boot libraries are included
nativeBuildInputs = [ghc] ++ executableToolDepends;
passthru = {
inherit (package) identifier;
config = component;
srcSubDir = cleanSrc'.subDir;
srcSubDirPath = cleanSrc'.root + cleanSrc'.subDir;
cleanSrc = cleanSrc';
dwarf = self (drvArgs // { enableDWARF = true; });
smallAddressSpace = self (drvArgs // { smallAddressSpace = true; });
exeName = "Setup";
};
meta = {
homepage = package.homepage or "";
description = package.synopsis or "";
license = haskellLib.cabalToNixpkgsLicense package.license;
platforms = if component.platforms == null then lib.platforms.all else component.platforms;
};
outputs = ["out" "configFiles"];
phases = ["unpackPhase" "patchPhase" "buildPhase" "installPhase" "installCheckPhase"];
buildPhase = ''
mkdir -p $configFiles
${configFiles.script}
runHook preBuild
if [[ ! -f ./Setup.hs && ! -f ./Setup.lhs ]]; then
cat ${defaultSetupSrc} > Setup.hs
fi
for f in Setup.hs Setup.lhs; do
if [ -f $f ]; then
echo Compiling package $f
ghc $f -threaded -package-env $configFiles/ghc-environment --make -o ./Setup
fi
done
[ -f ./Setup ] || (echo Failed to build Setup && exit 1)
runHook postBuild
'';
installPhase = ''
runHook preInstall
mkdir -p $out/bin
install ./Setup $out/bin/Setup
runHook postInstall
'';
doInstallCheck = true;
# Our aarch64-linux build sometimes wind up with files full of 0.
# This seems similar to an issue we had before that turned out
# to be low level disk issue in `cp` itself.
# This check might not prevent it, but may prevent invalid results
# making it into the store and nic cache (where they can be hard to
# remove).
installCheckPhase = ''
diff ./Setup $out/bin/Setup
'';
}
// lib.optionalAttrs (patches != []) {
patches = map (p:
if builtins.isFunction p
then p { inherit (package.identifier) version; }
else p) patches;
}
// hooks
);
in drv; in self