-
Notifications
You must be signed in to change notification settings - Fork 1
/
default.nix
266 lines (230 loc) · 10.2 KB
/
default.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
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
{
# Default GHC for Nixpkgs by default, for current default and explicitly supported GHCs https://search.nixos.org/packages?query=ghc&from=0&size=500&channel=unstable, Nixpkgs implicitly supports older minor versions also, until the configuration departs from compatibility with them.
# Compiler in a form ghc8101 <- GHC 8.10.1, just remove spaces and dots
compiler ? "default"
# Deafult.nix is a unit package abstraciton that allows to abstract over packages even in monorepos:
# Example: pass --arg cabalName --arg packageRoot "./subprojectDir", or map default.nix over a list of tiples for subprojects.
# cabalName is package resulting name: by default and on error resolves in haskellPackages.developPackage to project root directory name by default, but outside the haskellPackages.developPackage as you see below packageRoot can be different
, cabalName ? "replace"
, packageRoot ? pkgs.nix-gitignore.gitignoreSource [ ] ./.
# This settings expose most of the Nixpkgs Haskell.lib API: https://github.com/NixOS/nixpkgs/blob/master/pkgs/development/haskell-modules/lib.nix
# Some of these options implicitly enable other options they require, and some counterpoint options clash, obviously
# Don't fail at configure time if there are multiple versions of the same package in the (recursive) dependencies of the package being built. Will delay failures, if any, to compile time.
, allowInconsistentDependencies ? false
# Escape the version bounds from the cabal file. You may want to avoid this function.
, doJailbreak ? false
# Nix dependency checking, compilation and execution of test suites listed in the package description file.
, doCheck ? true
# Just produce a SDist src tarball
, sdistTarball ? false
# The strict packaging process as used on Hackage. Tests consistency of the Cabal file.
, buildFromSdist ? true
# Turn all warn into err with {-Wall,-Werror}
, failOnAllWarnings ? false
# `failOnAllWarnings` + `buildFromSdist`
, buildStrictly ? false
# 2020-06-02: NOTE: enableDeadCodeElimination = true: On GHC =< 8.8.3 macOS build falls due to https://gitlab.haskell.org/ghc/ghc/issues/17283
, enableDeadCodeElimination ? false
# Disabled GHC code optimizations make build/tolling/dev loops faster.
# Works also for Haskel IDE Engine and GHCID.
# Enable optimizations for production use, and to pass benchmarks.
, disableOptimization ? true
# Use faster `gold` ELF linker from GNU binutils instead of older&slower but more versatile GNU linker. Is not available by default since macOS does not have it.
, linkWithGold ? false
# Provide an inventory of performance events and timings for the execution. Provides informaiton in an absolute sense. Nothing is timestamped.
, enableLibraryProfiling ? false
, enableExecutableProfiling ? false
# Include tracing information & abilities. Tracing records the chronology, often with timestamps and is extensive in time
, doTracing ? false
# Include DWARF debugging information & abilities
, enableDWARFDebugging ? true
# Strip results from all debugging symbols
, doStrip ? false
# Nixpkgs expects shared libraries
, enableSharedLibraries ? true
# Ability to make static libraries
, enableStaticLibraries ? false
# Make hybrid executable that is also a shared library
, enableSharedExecutables ? false
# link executables statically against haskell libs to reduce closure size
, justStaticExecutables ? false
, enableSeparateBinOutput ? false
# checkUnusedPackages: is `failOnAllWarnings` + `cabal sdist` + post-build dep check.
# Currently uses `packunused` or GHC 8.8 internals, later switches into GHC internal feature.
# Adds a post-build check to verify that dependencies declared in the cabal file are actually used.
, checkUnusedPackages ? false
# Generation and installation of haddock API documentation
, doHaddock ? false
# Generate hyperlinked source code for documentation using HsColour, and have Haddock documentation link to it.
, doHyperlinkSource ? false
# Generation and installation of a coverage report. See https://wiki.haskell.org/Haskell_program_coverage
, doCoverage ? false
# doBenchmark: Dependency checking + compilation and execution for benchmarks listed in the package description file.
, doBenchmark ? false
# For binaries named in `executableNamesToShellComplete` list, generate and bundle-into package an automatically loaded shell complettions
, generateOptparseApplicativeCompletions ? false
, executableNamesToShellComplete ? [ "executableToComplete" ]
# Include Hoogle into derivation
, withHoogle ? true
# Nix by default updates and uses locally configured nixpkgs-unstable channel
# Nixpkgs revision options:
# `rev` vals in order of freshness -> cache & stability:
# { master
# , <commitHash>
# , haskell-updates # Haskell development branch in Nixpkgs, can be inconsistent. Weekly merged into the upstream
# , nixpkgs-unstable # Default branch on Nix installation, default for non NixOS
# , nixos-unstable # nixpkgs-unstable that passes a bunch of base tests
# , nixos-20.03 # Last stable release, gets almost no updates to recipes, gets only required backports
# ...
# }
, rev ? "default"
, pkgs ?
if builtins.compareVersions builtins.nixVersion "2.0" < 0
then abort "Requires Nix >= 2.0"
else
if ((rev == "") || (rev == "default") || (rev == "local"))
then import <nixpkgs> {}
# Do not guard with hash, so the project is able to use current channels (rolling `rev`) of Nixpkgs
else import (builtins.fetchTarball "https://github.com/NixOS/nixpkgs/archive/${rev}.tar.gz") {}
// {
# Try to build dependencies even if they are marked broken.
config.allowBroken = true;
}
, mkDerivation ? null
}:
let
getDefaultGHC = "ghc${
(
# Remove '.' from the string 8.8.4 -> 884
pkgs.lib.stringAsChars (c: if c == "." then "" else c)
# Get default GHC version,
(pkgs.lib.getVersion pkgs.haskellPackages.ghc)
)
}";
compilerPackage =
if ((compiler == "") || (compiler == "default"))
then getDefaultGHC
else compiler;
# side-overlay = pkgs.fetchFromGitHub {
# owner = "replaceWithAccount";
# repo = "replaceWithRepo";
# rev = "0.0.0.0";
# sha256 = "1qf5rn43d46vgqqgmwqdkjh78rfg6bcp4kypq3z7mx46sdpzvb78";
# };
overlay = pkgs.lib.foldr pkgs.lib.composeExtensions (_: _: {}) [
# (import "${side-overlay}/overlay.nix")
(self: super:
pkgs.lib.optionalAttrs withHoogle {
ghc = super.ghc // { withPackages = super.ghc.withHoogle; };
ghcWithPackages = self.ghc.withPackages;
})
];
overrideHaskellPackages = orig: {
buildHaskellPackages =
orig.buildHaskellPackages.override overrideHaskellPackages;
overrides = if orig ? overrides
then pkgs.lib.composeExtensions orig.overrides overlay
else overlay;
};
haskellPackages = pkgs.haskell.packages.${compilerPackage}.override
overrideHaskellPackages;
# Application of functions from this list to the package in code here happens in the reverse order (from the tail). Some options depend on & override others, so if enabling options caused Nix error or not expected result - change the order, and please do not change this order without proper testing.
listSwitchFunc =
[
{
switch = sdistTarball;
function = pkgs.haskell.lib.sdistTarball;
}
{
switch = buildFromSdist;
function = pkgs.haskell.lib.buildFromSdist;
}
{
switch = buildStrictly;
function = pkgs.haskell.lib.buildStrictly;
}
{
switch = disableOptimization;
function = pkgs.haskell.lib.disableOptimization;
}
{
switch = doJailbreak;
function = pkgs.haskell.lib.doJailBreak;
}
{
switch = doStrip;
function = pkgs.haskell.lib.doStrip;
}
{
switch = enableDWARFDebugging;
function = pkgs.haskell.lib.enableDWARFDebugging;
}
{
switch = linkWithGold;
function = pkgs.haskell.lib.linkWithGold;
}
{
switch = failOnAllWarnings;
function = pkgs.haskell.lib.failOnAllWarnings;
}
{
switch = justStaticExecutables;
function = pkgs.haskell.lib.justStaticExecutables;
}
{
switch = checkUnusedPackages;
function = pkgs.haskell.lib.checkUnusedPackages {};
}
{
switch = generateOptparseApplicativeCompletions;
function = pkgs.haskell.lib.generateOptparseApplicativeCompletions executableNamesToShellComplete;
}
{
switch = doHyperlinkSource;
function = pkgs.haskell.lib.doHyperlinkSource;
}
];
# Function that applies enabled option to the package, used in the fold.
onSwitchApplyFunc = set: object:
if set.switch
then set.function object
else object;
# General description of package
package = haskellPackages.developPackage {
name = cabalName;
# Do not include into closure the files listed in .gitignore
root = packageRoot;
modifier = drv: pkgs.haskell.lib.overrideCabal drv (attrs: {
buildTools = (attrs.buildTools or []) ++ [
haskellPackages.cabal-install
];
# testHaskellDepends = attrs.testHaskellDepends ++ [
# pkgs.nix
# haskellPackages.criterion
# ];
# Declare that the header set arguments as according Haskell.lib switches
inherit allowInconsistentDependencies;
inherit doCheck;
inherit enableDeadCodeElimination;
inherit enableLibraryProfiling;
inherit enableExecutableProfiling;
inherit enableSharedLibraries;
inherit enableStaticLibraries;
inherit enableSharedExecutables;
inherit enableSeparateBinOutput;
inherit doBenchmark;
inherit doCoverage;
inherit doHaddock;
configureFlags = pkgs.stdenv.lib.optional doTracing "--flags=tracing";
passthru = {
nixpkgs = pkgs;
inherit haskellPackages;
};
});
returnShellEnv = false;
};
# One part of Haskell.lib options are argument switches, those are in `inherit`ed list.
# Other part - are function wrappers over pkg. Fold allows to compose those.
# composePackage = foldr (if switch then function) (package) ([{switch,function}]) == (functionN .. (function1 package))
composedPackage = pkgs.lib.foldr (onSwitchApplyFunc) package listSwitchFunc;
in composedPackage