This repository has been archived by the owner on Nov 20, 2023. It is now read-only.
forked from IntersectMBO/cardano-node
-
Notifications
You must be signed in to change notification settings - Fork 0
/
haskell.nix
390 lines (383 loc) · 19.1 KB
/
haskell.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
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
############################################################################
# Builds Haskell packages with Haskell.nix
############################################################################
{ haskell-nix
, incl
, CHaP
}:
let
inherit (haskell-nix) haskellLib;
# This creates the Haskell package set.
# https://input-output-hk.github.io/haskell.nix/user-guide/projects/
project = haskell-nix.cabalProject' ({ pkgs
, lib
, config
, buildProject
, ...
}:
{
src = ../.;
name = "cardano-node";
compiler-nix-name = lib.mkDefault "ghc8107";
# extra-compilers
flake.variants = lib.genAttrs ["ghc927"] (x: {compiler-nix-name = x;});
cabalProjectLocal = ''
repository cardano-haskell-packages-local
url: file:${CHaP}
secure: True
active-repositories: hackage.haskell.org, cardano-haskell-packages-local
allow-newer: terminfo:base
'' + lib.optionalString pkgs.stdenv.hostPlatform.isWindows ''
-- When cross compiling we don't have a `ghc` package
package plutus-tx-plugin
flags: +use-ghc-stub
'';
inputMap = {
"https://input-output-hk.github.io/cardano-haskell-packages" = CHaP;
};
shell = {
name = "cabal-dev-shell";
# These programs will be available inside the nix-shell.
nativeBuildInputs = with pkgs.pkgsBuildBuild; [
nix-prefetch-git
pkg-config
hlint
ghcid
haskell-language-server
cabal
];
withHoogle = true;
};
# Additional configuration for the project package set
# ----------------------------------------------------
#
# The following configuration influeces how the project package set
# is built by nix. The configuration uses the same modular system as
# NixOS.
#
# For additional background information see
#
# https://nixos.org/manual/nixos/stable/index.html#sec-writing-modules
#
# For a list of all configuration options supported by Haskell.nix see
#
# https://input-output-hk.github.io/haskell.nix/reference/modules.html
#
# Tips:
#
# 1. Nix is a lazy language and the resulting `project` is already
# in scope. Avoid referring to any of `project` attributes from
# within a configuration module. You can instead refer to the final
# package set configuration in `config`. If you run into infinite
# resursion issues, troubleshooting the latter will be much easier
# than troubleshooting the former.
#
# 2. The same configuration option can be set to different values
# from separate modules. How these values will be merged together
# dependes on the type of the option. The type of each option is
# listed in the haskell.nix modules reference pages.
#
# 3. The option `packages` is an attrset of submodules, i.e. each
# package has its own modular configuration. Similarly, `.components`
# is an attrset of submodules inside each package.
#
# 4. You can specify a configuration for every package by adding a
# module to the definition of `packages` itself, i.e:
#
# {
# options.packages = lib.mkOption {
# type = lib.types.attrsOf (lib.types.submodule (
# { config, name, ... }:
# # ^-- package name passed as a extra argument
# # ^-- this is now the final package configuration
# {
# # e.g.
# configureFlags = [ "--ghc-option=-Werror"];
# }
# ));
# }
#
# The same applies to every component inside a package.
#
modules =
[
({ lib, pkgs, ... }: {
packages.cardano-tracer.package.buildable = with pkgs.stdenv.hostPlatform; lib.mkForce (!isMusl);
packages.cardano-node-chairman.components.tests.chairman-tests.buildable = lib.mkForce pkgs.stdenv.hostPlatform.isUnix;
packages.plutus-tx-plugin.components.library.platforms = with lib.platforms; [ linux darwin ];
packages.tx-generator.package.buildable = with pkgs.stdenv.hostPlatform; !isMusl;
packages.cardano-ledger-alonzo.components.library.doHaddock = false;
packages.cardano-ledger-babbage.components.library.doHaddock = false;
packages.cardano-ledger-conway.components.library.doHaddock = false;
packages.cardano-protocol-tpraos.components.library.doHaddock = false;
})
({ lib, pkgs, ... }: {
# Needed for the CLI tests.
# Coreutils because we need 'paste'.
packages.cardano-testnet.components.tests.cardano-testnet-tests.build-tools =
lib.mkForce (with pkgs.buildPackages; [ jq coreutils shellcheck lsof ]);
})
({ lib, pkgs, ... }: {
# Use the VRF fork of libsodium
packages.cardano-crypto-praos.components.library.pkgconfig = lib.mkForce [ [ pkgs.libsodium-vrf ] ];
packages.cardano-crypto-class.components.library.pkgconfig = lib.mkForce [ [ pkgs.libsodium-vrf pkgs.secp256k1 pkgs.libblst ] ];
})
({ lib, pkgs, ... }:
let postInstall = exeName: ''
BASH_COMPLETIONS=$out/share/bash-completion/completions
ZSH_COMPLETIONS=$out/share/zsh/site-functions
mkdir -p $BASH_COMPLETIONS $ZSH_COMPLETIONS
$out/bin/${exeName} --bash-completion-script ${exeName} > $BASH_COMPLETIONS/${exeName}
$out/bin/${exeName} --zsh-completion-script ${exeName} > $ZSH_COMPLETIONS/_${exeName}
'';
in lib.mkIf (!pkgs.stdenv.hostPlatform.isWindows)
{
# add shell completion:
packages.cardano-node.components.exes.cardano-node.postInstall = postInstall "cardano-node";
packages.cardano-cli.components.exes.cardano-cli.postInstall = postInstall "cardano-cli";
packages.cardano-topology.components.exes.cardano-topology.postInstall = postInstall "cardano-topology";
packages.locli.components.exes.locli.postInstall = postInstall "locli";
})
({ lib, pkgs, config, ... }:
let
exportCliPath = "export CARDANO_CLI=${config.hsPkgs.cardano-cli.components.exes.cardano-cli}/bin/cardano-cli${pkgs.stdenv.hostPlatform.extensions.executable}";
exportNodePath = "export CARDANO_NODE=${config.hsPkgs.cardano-node.components.exes.cardano-node}/bin/cardano-node${pkgs.stdenv.hostPlatform.extensions.executable}";
mainnetConfigFiles = [
"configuration/cardano/mainnet-config.yaml"
"configuration/cardano/mainnet-config.json"
"configuration/cardano/mainnet-byron-genesis.json"
"configuration/cardano/mainnet-shelley-genesis.json"
"configuration/cardano/mainnet-alonzo-genesis.json"
"configuration/cardano/mainnet-conway-genesis.json"
];
goldenConfigFiles = [
"configuration/defaults/byron-mainnet"
"cardano-testnet/test/cardano-testnet-golden/files/golden/allegra_node_default_config.json"
"cardano-testnet/test/cardano-testnet-golden/files/golden/alonzo_node_default_config.json"
"cardano-testnet/test/cardano-testnet-golden/files/golden/babbage_node_default_config.json"
"cardano-testnet/test/cardano-testnet-golden/files/golden/byron_node_default_config.json"
"cardano-testnet/test/cardano-testnet-golden/files/golden/conway_node_default_config.json"
"cardano-testnet/test/cardano-testnet-golden/files/golden/mary_node_default_config.json"
"cardano-testnet/test/cardano-testnet-golden/files/golden/shelley_node_default_config.json"
"cardano-testnet/files/data/alonzo/genesis.alonzo.spec.json"
"cardano-testnet/files/data/conway/genesis.conway.spec.json"
];
in
{
# split data output for ekg to reduce closure size
packages.ekg.components.library.enableSeparateDataOutput = true;
packages.cardano-node-chairman.components.tests.chairman-tests.build-tools =
lib.mkForce [
pkgs.lsof
config.hsPkgs.cardano-node.components.exes.cardano-node
config.hsPkgs.cardano-cli.components.exes.cardano-cli
config.hsPkgs.cardano-node-chairman.components.exes.cardano-node-chairman
];
# cardano-node-chairman depends on cardano-node and cardano-cli, and some config files
packages.cardano-node-chairman.preCheck =
let
# This define files included in the directory that will be passed to `H.getProjectBase` for this test:
filteredProjectBase = incl ../. goldenConfigFiles;
in
''
${exportCliPath}
${exportNodePath}
export CARDANO_NODE_CHAIRMAN=${config.hsPkgs.cardano-node-chairman.components.exes.cardano-node-chairman}/bin/cardano-node-chairman${pkgs.stdenv.hostPlatform.extensions.executable}
export CARDANO_NODE_SRC=${filteredProjectBase}
'';
# cardano-testnet depends on cardano-node, cardano-cli, cardano-submit-api and some config files
packages.cardano-node.components.tests.cardano-node-test.preCheck =
let
# This define files included in the directory that will be passed to `H.getProjectBase` for this test:
filteredProjectBase = incl ../. mainnetConfigFiles;
in
''
export CARDANO_NODE_SRC=${filteredProjectBase}
'';
packages.cardano-testnet.preCheck =
let
# This define files included in the directory that will be passed to `H.getProjectBase` for this test:
filteredProjectBase = incl ../. (mainnetConfigFiles ++ goldenConfigFiles ++ [
"configuration/cardano/mainnet-topology.json"
"configuration/cardano/mainnet-conway-genesis.json"
"scripts/babbage/alonzo-babbage-test-genesis.json"
"scripts/babbage/conway-babbage-test-genesis.json"
]);
in
''
${exportCliPath}
${exportNodePath}
export CARDANO_SUBMIT_API=${config.hsPkgs.cardano-submit-api.components.exes.cardano-submit-api}/bin/cardano-submit-api${pkgs.stdenv.hostPlatform.extensions.executable}
export CARDANO_NODE_SRC=${filteredProjectBase}
''
# the cardano-testnet-tests, use sockets stored in a temporary directory
# however on macOS the socket path's max is 104 chars. The package name
# is already long, and as such the constructed socket path
#
# /private/tmp/nix-build-cardano-testnet-test-cardano-testnet-tests-1.36.0-check.drv-1/chairman-test-93c5d9288dd8e6bc/socket/node-bft1
#
# exceeds taht limit easily. We therefore set a different tmp directory
# during the preBuild phase.
+ ''
# unset TMPDIR, otherwise mktemp will use that as a base
unset TMPDIR
export TMPDIR=$(mktemp -d)
export TMP=$TMPDIR
'';
packages.cardano-testnet.components.tests.cardano-testnet-golden.preCheck =
let
# This define files included in the directory that will be passed to `H.getProjectBase` for this test:
filteredProjectBase = incl ../. [
"cardano-testnet/test/cardano-testnet-golden/files/golden/allegra_node_default_config.json"
"cardano-testnet/test/cardano-testnet-golden/files/golden/alonzo_node_default_config.json"
"cardano-testnet/test/cardano-testnet-golden/files/golden/babbage_node_default_config.json"
"cardano-testnet/test/cardano-testnet-golden/files/golden/byron_node_default_config.json"
"cardano-testnet/test/cardano-testnet-golden/files/golden/conway_node_default_config.json"
"cardano-testnet/test/cardano-testnet-golden/files/golden/mary_node_default_config.json"
"cardano-testnet/test/cardano-testnet-golden/files/golden/shelley_node_default_config.json"
];
in
''
${exportCliPath}
export CARDANO_TESTNET=${config.hsPkgs.cardano-testnet.components.exes.cardano-testnet}/bin/cardano-testnet${pkgs.stdenv.hostPlatform.extensions.executable}
export CARDANO_NODE_SRC=${filteredProjectBase}
'';
# cardano-tracer-test-ext, will default to /tmp/testTracerExt, which means
# if this test is run in parallel, things will just hang; or break.
packages.cardano-tracer.components.tests.cardano-tracer-test-ext.preCheck = ''
# unset TMPDIR, otherwise mktemp will use that as a base
unset TMPDIR
export TMPDIR=$(mktemp -d)
export TMP=$TMPDIR
mkdir $TMP/testTracerExt
# workaround the broken --workdir argument parser.
# (it doesn't properly strip args before passing them to tasty;
# also needs them to be quoted)
export WORKDIR=$TMP/testTracerExt
'';
})
({ lib, pkgs, ... }: lib.mkIf (!pkgs.stdenv.hostPlatform.isDarwin) {
# Needed for profiled builds to fix an issue loading recursion-schemes part of makeBaseFunctor
# that is missing from the `_p` output. See https://gitlab.haskell.org/ghc/ghc/-/issues/18320
# This work around currently breaks regular builds on macOS with:
# <no location info>: error: ghc: ghc-iserv terminated (-11)
packages.plutus-core.components.library.ghcOptions = [ "-fexternal-interpreter" ];
})
({ lib, ... }: {
options.packages = lib.mkOption {
type = lib.types.attrsOf (lib.types.submodule (
{ config, lib, ... }:
lib.mkIf config.package.isLocal
{
configureFlags = [ "--ghc-option=-Werror"];
}
));
};
})
({ lib, pkgs, ... }: lib.mkIf pkgs.stdenv.hostPlatform.isLinux {
# systemd can't be statically linked
packages.cardano-git-rev.flags.systemd = !pkgs.stdenv.hostPlatform.isMusl;
packages.cardano-node.flags.systemd = !pkgs.stdenv.hostPlatform.isMusl;
packages.cardano-tracer.flags.systemd = !pkgs.stdenv.hostPlatform.isMusl;
})
# disable haddock
# Musl libc fully static build
({ lib, ... }: {
options.packages = lib.mkOption {
type = lib.types.attrsOf (lib.types.submodule (
{ config, lib, pkgs, ...}:
lib.mkIf (pkgs.stdenv.hostPlatform.isMusl && config.package.isLocal)
{
# Module options which adds GHC flags and libraries for a fully static build
enableShared = false;
enableStatic = true;
}
));
};
config =
lib.mkIf pkgs.stdenv.hostPlatform.isMusl
{
# Haddock not working and not needed for cross builds
doHaddock = false;
packages.cardano-cli.enableShared = false;
packages.cardano-cli.enableStatic = true;
# Needed for TH code in cardano-cli
packages.cardano-git-rev.enableShared = lib.mkForce true;
};
})
({ lib, pkgs, ... }: lib.mkIf (pkgs.stdenv.hostPlatform != pkgs.stdenv.buildPlatform) {
# Remove hsc2hs build-tool dependencies (suitable version will be available as part of the ghc derivation)
packages.Win32.components.library.build-tools = lib.mkForce [ ];
packages.terminal-size.components.library.build-tools = lib.mkForce [ ];
packages.network.components.library.build-tools = lib.mkForce [ ];
})
({ ... }: {
# TODO: requires
# https://github.com/input-output-hk/ouroboros-network/pull/4673 or
# a newer ghc
packages.ouroboros-network-framework.doHaddock = false;
})
# TODO add flags to packages (like cs-ledger) so we can turn off tests that will
# not build for windows on a per package bases (rather than using --disable-tests).
# configureArgs = lib.optionalString stdenv.hostPlatform.isWindows "--disable-tests";
];
});
in
project.appendOverlays (with haskellLib.projectOverlays; [
projectComponents
(final: prev:
let inherit (final.pkgs) lib; in {
profiled = final.appendModule {
modules = [{
enableLibraryProfiling = true;
packages.cardano-node.components.exes.cardano-node.enableProfiling = true;
packages.tx-generator.components.exes.tx-generator.enableProfiling = true;
packages.locli.components.exes.locli.enableProfiling = true;
}
{
packages = final.pkgs.lib.genAttrs
[ "cardano-node"
"cardano-tracer"
"trace-dispatcher"
"trace-forward"
"trace-resources"
]
(name: { configureFlags = [ "--ghc-option=-fprof-auto" ]; });
}];
};
asserted = final.appendModule {
modules = [{
packages = lib.genAttrs [
"ouroboros-consensus"
"ouroboros-consensus-cardano"
"ouroboros-network"
"network-mux"
]
(name: { flags.asserts = true; });
}];
};
eventlogged = final.appendModule
{
modules = [{
packages = final.pkgs.lib.genAttrs [ "cardano-node" ]
(name: { configureFlags = [ "--ghc-option=-eventlog" ]; });
}];
};
# add passthru and gitrev to hsPkgs:
hsPkgs = lib.mapAttrsRecursiveCond (v: !(lib.isDerivation v))
(path: value:
if (lib.isAttrs value) then
lib.recursiveUpdate
value
{
# Also add convenient passthru to some alternative compilation configurations:
passthru = {
profiled = lib.getAttrFromPath path final.profiled.hsPkgs;
asserted = lib.getAttrFromPath path final.asserted.hsPkgs;
eventlogged = lib.getAttrFromPath path final.eventlogged.hsPkgs;
};
}
else value)
prev.hsPkgs;
})
])