1# Nim {#sec-language-nim}
2
3The Nim compiler and a builder function is available.
4Nim programs are built using a lockfile and either `buildNimPackage` or `buildNimSbom`.
5
6## buildNimPackage {#buildNimPackage}
7
8The following example shows a Nim program that depends only on Nim libraries:
9```nix
10{
11 lib,
12 buildNimPackage,
13 fetchFromGitHub,
14}:
15
16buildNimPackage (finalAttrs: {
17 pname = "ttop";
18 version = "1.2.7";
19
20 src = fetchFromGitHub {
21 owner = "inv2004";
22 repo = "ttop";
23 rev = "v${finalAttrs.version}";
24 hash = lib.fakeHash;
25 };
26
27 lockFile = ./lock.json;
28
29 nimFlags = [
30 "-d:NimblePkgVersion=${finalAttrs.version}"
31 ];
32})
33```
34
35### `buildNimPackage` parameters {#buildnimpackage-parameters}
36
37The `buildNimPackage` function takes an attrset of parameters that are passed on to `stdenv.mkDerivation`.
38
39The following parameters are specific to `buildNimPackage`:
40
41* `lockFile`: JSON formatted lockfile.
42* `nimbleFile`: Specify the Nimble file location of the package being built
43 rather than discover the file at build-time.
44* `nimRelease ? true`: Build the package in *release* mode.
45* `nimDefines ? []`: A list of Nim defines. Key-value tuples are not supported.
46* `nimFlags ? []`: A list of command line arguments to pass to the Nim compiler.
47 Use this to specify defines with arguments in the form of `-d:${name}=${value}`.
48* `nimDoc` ? false`: Build and install HTML documentation.
49
50### Lockfiles {#nim-lockfiles}
51Nim lockfiles are created with the `nim_lk` utility.
52Run `nim_lk` with the source directory as an argument and it will print a lockfile to stdout.
53```sh
54$ cd nixpkgs
55$ nix build -f . ttop.src
56$ nix run -f . nim_lk ./result | jq --sort-keys > pkgs/by-name/tt/ttop/lock.json
57```
58
59## buildNimSbom {#buildNimSbom}
60
61An alternative to `buildNimPackage` is `buildNimSbom` which builds packages from [CycloneDX SBOM](https://cyclonedx.org/) files.
62`buildNimSbom` resolves Nim dependencies to [fixed-output derivations](https://nixos.org/manual/nix/stable/glossary#gloss-fixed-output-derivation) using the [nix:fod namespace](#sec-interop.cylonedx-fod).
63
64In the following minimal example only the source code checkout and a `buildInput` are specified.
65The SBOM file provides metadata such as `pname` and `version` as well as the sources to Nim dependencies.
66```nix
67# pkgs/by-name/ni/nim_lk/package.nix
68{
69 lib,
70 buildNimSbom,
71 fetchFromSourcehut,
72 openssl,
73}:
74
75buildNimSbom (finalAttrs: {
76 src = fetchFromSourcehut {
77 owner = "~ehmry";
78 repo = "nim_lk";
79 rev = finalAttrs.version;
80 hash = lib.fakeHash;
81 };
82 buildInputs = [ openssl ];
83}) ./sbom.json
84```
85
86### Generating SBOMs {#generating-nim-sboms}
87
88The [nim_lk](https://git.sr.ht/~ehmry/nim_lk) utility can generate SBOMs from [Nimble](https://github.com/nim-lang/nimble) package metadata.
89See the [nim_lk documentation](https://git.sr.ht/~ehmry/nim_lk#nimble-to-cyclonedx-sbom) for more information.
90
91## Overriding Nim packages {#nim-overrides}
92
93The `buildNimPackage` and `buildNimSbom` functions generate flags and additional build dependencies from the `lockFile` parameter passed to `buildNimPackage`. Using [`overrideAttrs`](#sec-pkg-overrideAttrs) on the final package will apply after this has already been generated, so this can't be used to override the `lockFile` in a package built with `buildNimPackage`. To be able to override parameters before flags and build dependencies are generated from the `lockFile`, use `overrideNimAttrs` instead with the same syntax as `overrideAttrs`:
94
95```nix
96pkgs.nitter.overrideNimAttrs {
97 # using a different source which has different dependencies from the standard package
98 src = pkgs.fetchFromGithub {
99 # …
100 };
101 # new lock file generated from the source
102 lockFile = ./custom-lock.json;
103}
104```
105
106## Lockfile dependency overrides {#nim-lock-overrides}
107
108The `buildNimPackage` function matches the libraries specified by `lockFile` to attrset of override functions that are then applied to the package derivation.
109The default overrides are maintained as the top-level `nimOverrides` attrset at `pkgs/top-level/nim-overrides.nix`.
110
111For example, to propagate a dependency on SDL2 for lockfiles that select the Nim `sdl2` library, an overlay is added to the set in the `nim-overrides.nix` file:
112```nix
113{
114 lib,
115 # …
116 SDL2,
117# …
118}:
119
120{
121 # …
122 sdl2 =
123 lockAttrs:
124 {
125 buildInputs ? [ ],
126 ...
127 }:
128 {
129 buildInputs = buildInputs ++ [ SDL2 ];
130 };
131 # …
132}
133```
134
135The annotations in the `nim-overrides.nix` set are functions that take two arguments and return a new attrset to be overlaid on the package being built.
136- lockAttrs: the attrset for this library from within a lockfile. This can be used to implement library version constraints, such as marking libraries as broken or insecure.
137- prevAttrs: the attrset produced by initial arguments to `buildNimPackage` and any preceding lockfile overlays.
138
139### Overriding an Nim library override {#nim-lock-overrides-overrides}
140
141The `nimOverrides` attrset makes it possible to modify overrides in a few different ways.
142
143Override a package internal to its definition:
144```nix
145{
146 lib,
147 buildNimPackage,
148 nimOverrides,
149 libressl,
150}:
151
152let
153 buildNimPackage' = buildNimPackage.override {
154 nimOverrides = nimOverrides.override { openssl = libressl; };
155 };
156in
157buildNimPackage' (finalAttrs: {
158 pname = "foo";
159 # …
160})
161```
162
163Override a package externally:
164```nix
165{ pkgs }:
166{
167 foo = pkgs.foo.override {
168 buildNimPackage = pkgs.buildNimPackage.override {
169 nimOverrides = pkgs.nimOverrides.override { openssl = libressl; };
170 };
171 };
172}
173```