Skip to content

Commit 354c1ea

Browse files
authored
Improve documentation of the nix code (#7321)
1 parent 8d810d4 commit 354c1ea

File tree

9 files changed

+81
-15
lines changed

9 files changed

+81
-15
lines changed

nix/README.md

Lines changed: 35 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,49 @@
11
# DevEnv & CI - Maintenance Guide & Troubleshooting
22

3-
This document is intended both for maintainers of the nix code and for developers facing issues with their development environment or with the CI system.
3+
This document is intended both for maintainers of the nix code and for developers facing issues with their development environment or with the CI system. Use CTRL-F to look for relevant keywords.
44

5-
# Troubleshooting
5+
### 1) `nix develop` fails to enter the shell, `cabal build` fails when it shouldn't.
66

7+
In general when facing any problem related to the nix shell or cabal failing to build when it shouldn't, the first step is to make sure you are using the latest shell from master: first exit the nix shell, then `git pull --rebase origin master`, then re-enter the nix shell (i.e. run `nix develop`).
78

8-
<div style="background-color: #FFFF0033; padding: 5px;">
9+
If that fails, you might be facing a caching issue. In that case, try this before exiting and re-entering the nix shell:
910

10-
`nix develop` fails to enter the shell, `cabal build` fails when it shouldn't.
11+
`rm -r ~/.cabal/{store,packages} plutus-metatheory/_build dist dist-newstyle`
1112

12-
</div>
13+
### 2) `nix develop` is updating the `flake.lock` file.
1314

14-
In general when facing any problem related to the nix shell or cabal failing to build when it shouldn't, the first step is to make sure you are using the latest shell from master: first exit the nix shell, then `git pull --rebase origin master`, then re-enter the nix shell (i.e. run `nix develop`).
15+
This should never happen, it is a bug in nix, and has been observed in version `2.26.1`.
16+
Downgrade or upgrade your nix installation to fix this issue.
1517

16-
If that fails, you might be facing a caching issue. In that case, try this before exiting and re-entering the nix shell:
18+
### 3) `cabal test all` fails
1719

18-
```
19-
rm -r ~/.cabal/{store,packages} plutus-metatheory/_build dist dist-newstyle
20-
```
20+
Sometimes cabal needs a `cabal build all` before it can successfully execute a `cabal test all`.
2121

22-
<div style="background-color: #FFFF0033; padding: 5px;">
22+
### 4) How to update `hackage`, `haskell.nix` and `CHaP`
2323

24-
`nix develop` is updating the `flake.lock` file.
25-
</div>
24+
`nix flake update haskell-nix` updates [haskell.nix](https://github.com/input-output-hk/haskell.nix).
25+
This should be done infrequently as it is likely to break the nix code.
26+
If you just want new packages from `hackage` or `CHaP` instead, you can independently run:
27+
`nix flake update hackage CHaP`.
28+
Then you can change the `index-state` in `cabal.project`: you pick an arbitrary date, and if it's too new, `cabal` will error out and suggest the latest known date which you can copy-paste.
2629

27-
This should never happen, it is a bug in nix, and has been observed in version `2.26.1`.
28-
Downgrade your nix installation to fix this issue.
30+
### 5) How to change what gets build in CI
31+
32+
Modify `nested-ci-jobs = {..}` in [./nix/outputs.nix](https://github.com/input-output-hk/haskell.nix).
33+
34+
### 6) How to change what gets exposed in the flake outputs
35+
36+
Modify `packages = {..}` in [./nix/outputs.nix](https://github.com/input-output-hk/haskell.nix).
37+
38+
### 7) How to build fully static Haskell executables with Nix
39+
40+
Look at `static-haskell-packages = {..}` in [./nix/outputs.nix](https://github.com/input-output-hk/haskell.nix).
41+
42+
### 8) How to manage cross-compilation on Windows via Wine with Nix
43+
44+
Look at `windows-hydra-jobs = {..}` in [./nix/outputs.nix](https://github.com/input-output-hk/haskell.nix).
45+
46+
### 9) How to define build variants and cabal flags in the nix code
2947

48+
The nix builds can be overridden inside [./nix/project.nix](https://github.com/input-output-hk/haskell.nix).
49+
New cabal flags and configuration options can be defined there.

nix/agda-tools.nix

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
let
44

5+
# Agda standard library pinned to v2.1.1.
6+
# Used in: `nix/metatheory.nix` (as a build input) and `nix/shell.nix` (via agda-with-stdlib).
57
agda-stdlib = agda-packages.standard-library.overrideAttrs (oldAtts: rec {
68

79
version = "2.1.1";
@@ -26,6 +28,8 @@ let
2628
'';
2729
});
2830

31+
# Compose a tailored Agda toolchain and expose it via agdaPackages.
32+
# Used in: `nix/metatheory.nix` (to build agda-with-stdlib-and-metatheory) and `nix/shell.nix`.
2933
# We want to keep control of which version of Agda we use, so we supply our own and override
3034
# the one from nixpkgs.
3135
#
@@ -68,6 +72,8 @@ let
6872
pkgs = frankenPkgs;
6973
};
7074

75+
# Patches Agda's build to compile interface files post-install.
76+
# Used in: `agda-project` below via `modules`.
7177
# Agda is a huge pain. They have a special custom setup that compiles the
7278
# interface files for the Agda that ships with the compiler. These go in
7379
# the data files for the *library*, but they require the *executable* to
@@ -101,16 +107,21 @@ let
101107
'';
102108
};
103109

110+
# Default patch module (native toolchain).
104111
agda-project-module-patch-default =
105112
agda-project-module-patch { compiler-nix-name = "ghc"; };
106113

114+
# Patch module for static musl64 toolchain.
107115
agda-project-module-patch-musl64 =
108116
agda-project-module-patch { compiler-nix-name = "x86_64-unknown-linux-musl-ghc"; };
109117

118+
# The Agda executable from the built project.
110119
agda = agda-project.hsPkgs.Agda.components.exes.agda;
111120

121+
# The Agda mode executable.
112122
agda-mode = agda-project.hsPkgs.Agda.components.exes.agda-mode;
113123

124+
# Convenience wrapper providing `agda-with-stdlib` binary.
114125
agda-with-stdlib = pkgs.stdenv.mkDerivation {
115126
name = "agda-with-stdlib";
116127
phases = "installPhase";
@@ -121,6 +132,7 @@ let
121132
'';
122133
};
123134

135+
# The Agda hackage project used to produce the tools above.
124136
agda-project = pkgs.haskell-nix.hackage-project {
125137
name = "Agda";
126138
version = "2.7.0";
@@ -129,6 +141,7 @@ let
129141
modules = [ agda-project-module-patch-default ];
130142
};
131143

144+
# Path to the stdlib .agda-lib file for shell export.
132145
NIX_AGDA_STDLIB = "${agda-stdlib}/stadard-library.agda-lib";
133146

134147
in

nix/build-latex-doc.nix

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
{ pkgs, lib, agda-tools }:
22

3+
# Builds a LaTeX/Agda-based document into a PDF.
4+
# Used in: `nix/latex-documents.nix` to define all document derivations.
5+
36
{ name, description, src, output-pdf-name ? "*.pdf" }:
47

58
pkgs.stdenv.mkDerivation {

nix/metatheory.nix

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
let
44

5+
# plutus-metatheory as an agda-package
56
metatheory-agda-package = agda-tools.agda-packages.mkDerivation {
67
name = "plutus-metatheory";
78
pname = "plutus-metatheory";
@@ -13,6 +14,7 @@ let
1314
meta = { };
1415
};
1516

17+
# Tarball of the Agda library sources for distribution as an artifact.
1618
metatheory-agda-library = pkgs.stdenv.mkDerivation {
1719
name = "metatheory-agda-library";
1820
src = lib.cleanSource (self + /plutus-metatheory);
@@ -26,11 +28,14 @@ let
2628
'';
2729
};
2830

31+
# Developer helper: generates MAlonzo Haskell code from the metatheory.
32+
# Used in: `nix/shell.nix` pre-commit hook and common tools.
2933
generate-malonzo-code = pkgs.writeShellScriptBin "generate-malonzo-code" ''
3034
cd "$(git rev-parse --show-toplevel)/plutus-metatheory"
3135
agda-with-stdlib --compile --ghc-dont-call-ghc src/Main.lagda.md
3236
'';
3337

38+
# Agda executable wrapper that includes both stdlib and the metatheory package.
3439
agda-with-stdlib-and-metatheory = pkgs.stdenv.mkDerivation {
3540
name = "agda-with-stdlib-and-metatheory";
3641
phases = "installPhase";

nix/pkgs.nix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
{ inputs, system }:
22

3+
# Provides `pkgs` with project overlays and workarounds.
34
import inputs.nixpkgs {
45
inherit system;
56
config = inputs.haskell-nix.config;

nix/project.nix

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
{ inputs, pkgs, lib, metatheory, r-with-packages, utils }:
33

44
let
5+
# Defines the Haskell project and its variants via haskell.nix.
56
cabalProject = pkgs.haskell-nix.cabalProject' ({ config, pkgs, ... }:
67
{
78
name = "plutus";
@@ -30,6 +31,7 @@ let
3031
inputMap = { "https://chap.intersectmbo.org/" = inputs.CHaP; };
3132

3233
sha256map = {
34+
# We need one of these for each source-repository-package stanza in cabal.project.
3335
"https://github.com/jaccokrijnen/plutus-cert"."e814b9171398cbdfecdc6823067156a7e9fc76a3" =
3436
"0srqvx0b819b5crrbsa9hz2fnr50ahqizvvm0wdmyq2bbpk2rka7";
3537
};

nix/r-with-packages.nix

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
{ pkgs }:
22

3+
# R wrapper with required packages for benchmarking and analysis.
4+
# Add more R packages here as needed.
5+
# Used in: `nix/project.nix` (as build-tools) and `nix/shell.nix` common tools.
36
pkgs.rWrapper.override {
47
packages = [
58
pkgs.rPackages.tidyverse

nix/shell.nix

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
let
44

5+
# Toolchain versions used in dev shells. Consumed by `project.shellFor`.
56
tools = project.tools {
67
# "latest" cabal would be 3.14.1.0 which breaks haddock generation.
78
# TODO update cabal version once haddock generation is fixed upstream.
@@ -14,6 +15,7 @@ let
1415
stylish-haskell = "latest";
1516
};
1617

18+
# Pre-commit hooks for the repo. Injects into shell via shellHook.
1719
pre-commit-check = inputs.pre-commit-hooks.lib.${pkgs.system}.run {
1820
src = ../.;
1921
hooks = {
@@ -63,11 +65,13 @@ let
6365
};
6466
};
6567

68+
# Add extra Linux-only packages to the dev shell here.
6669
linux-pkgs = lib.optionals pkgs.hostPlatform.isLinux [
6770
pkgs.papi
6871
pkgs.util-linux
6972
];
7073

74+
# Common packages/tools available in all shells.
7175
common-pkgs = [
7276
agda-tools.agda
7377
agda-tools.agda-with-stdlib
@@ -111,10 +115,12 @@ let
111115
pkgs.nodejs_20
112116
];
113117

118+
# Locale archive setup for glibc hosts. Needed to fix cabal build issues on some hosts.
114119
locale-archive-hook =
115120
lib.optionalString (pkgs.stdenv.hostPlatform.libc == "glibc")
116121
"export LOCALE_ARCHIVE=${pkgs.glibcLocales}/lib/locale/locale-archive";
117122

123+
# Full developer shell with many tools.
118124
full-shell = project.shellFor {
119125
name = "plutus-shell-${project.args.compiler-nix-name}";
120126

@@ -136,6 +142,7 @@ let
136142
};
137143

138144

145+
# Lightweight shell with minimal tools.
139146
quick-shell = project.shellFor {
140147
name = "plutus-shell-${project.args.compiler-nix-name}";
141148
tools = { cabal = "latest"; };
@@ -147,6 +154,7 @@ let
147154
};
148155

149156

157+
# Select shell by compiler used in the project variant.
150158
shell = {
151159
ghc967 = full-shell;
152160
ghc984 = quick-shell;

nix/utils.nix

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22

33
rec {
44

5+
# Flattens a nested attribute set of derivations into name/value pairs.
6+
# Used in: `nix/outputs.nix` (to build `flattened-ci-jobs` and `ciJobs`).
57
flattenDerivationTree = separator: set:
68
let
79
recurse = name: name':
@@ -17,6 +19,8 @@ rec {
1719
assert lib.typeOf set == "set"; lib.listToAttrs (flatten "" set);
1820

1921

22+
# Aggregates CI jobs which are required for Hydra to pass.
23+
# Used in: `nix/outputs.nix` (to compute `hydra-required-job`).
2024
makeHydraRequiredJob = { self, pkgs }:
2125
let
2226
clean-jobs =
@@ -30,20 +34,27 @@ rec {
3034
};
3135

3236

37+
# Retrieves the git revision from flake sourceInfo, or "unknown".
38+
# Used in: `nix/project.nix` (adds `__GIT_REV__` CPP macro to builds).
39+
# When the git tree is dirty, the sourceInfo attribute is missing from inputs.self.
3340
getSourceInfoRev = inputs:
3441
if inputs.self.sourceInfo ? rev then
3542
inputs.self.sourceInfo.rev
3643
else
3744
"unknown";
3845

3946

47+
# Converts flake sourceInfo lastModifiedDate to ISO-8601, or empty string.
48+
# Used in: `nix/project.nix` (adds `__GIT_COMMIT_DATE__` CPP macro).
49+
# When the git tree is dirty, the sourceInfo attribute is missing from inputs.self.
4050
getSourceInfoLastModifiedDate = inputs:
4151
if inputs.self.sourceInfo ? lastModifiedDate then
4252
date_YYYYMMDDHHmmSS_ToIso8601 inputs.self.sourceInfo.lastModifiedDate
4353
else
4454
"";
4555

4656

57+
# Helper to convert YYYYMMDDHHmmSS timestamps to ISO-8601.
4758
date_YYYYMMDDHHmmSS_ToIso8601 = ts:
4859
let
4960
year = lib.substring 0 4 ts;

0 commit comments

Comments
 (0)