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
|
# Nim {#sec-language-nim}
The Nim compiler and a builder function is available.
Nim programs are built using a lockfile and either `buildNimPackage` or `buildNimSbom`.
## buildNimPackage {#buildNimPackage}
The following example shows a Nim program that depends only on Nim libraries:
```nix
{ lib, buildNimPackage, fetchFromGitHub }:
buildNimPackage (finalAttrs: {
pname = "ttop";
version = "1.2.7";
src = fetchFromGitHub {
owner = "inv2004";
repo = "ttop";
rev = "v${finalAttrs.version}";
hash = lib.fakeHash;
};
lockFile = ./lock.json;
nimFlags = [
"-d:NimblePkgVersion=${finalAttrs.version}"
];
})
```
### `buildNimPackage` parameters {#buildnimpackage-parameters}
The `buildNimPackage` function takes an attrset of parameters that are passed on to `stdenv.mkDerivation`.
The following parameters are specific to `buildNimPackage`:
* `lockFile`: JSON formatted lockfile.
* `nimbleFile`: Specify the Nimble file location of the package being built
rather than discover the file at build-time.
* `nimRelease ? true`: Build the package in *release* mode.
* `nimDefines ? []`: A list of Nim defines. Key-value tuples are not supported.
* `nimFlags ? []`: A list of command line arguments to pass to the Nim compiler.
Use this to specify defines with arguments in the form of `-d:${name}=${value}`.
* `nimDoc` ? false`: Build and install HTML documentation.
### Lockfiles {#nim-lockfiles}
Nim lockfiles are created with the `nim_lk` utility.
Run `nim_lk` with the source directory as an argument and it will print a lockfile to stdout.
```sh
$ cd nixpkgs
$ nix build -f . ttop.src
$ nix run -f . nim_lk ./result | jq --sort-keys > pkgs/by-name/tt/ttop/lock.json
```
## buildNimSbom {#buildNimSbom}
An alternative to `buildNimPackage` is `buildNimSbom` which builds packages from [CycloneDX SBOM](https://cyclonedx.org/) files.
`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).
In the following minimal example only the source code checkout and a `buildInput` are specified.
The SBOM file provides metadata such as `pname` and `version` as well as the sources to Nim dependencies.
```nix
# pkgs/by-name/ni/nim_lk/package.nix
{
lib,
buildNimSbom,
fetchFromSourcehut,
openssl,
}:
buildNimSbom (finalAttrs: {
src = fetchFromSourcehut {
owner = "~ehmry";
repo = "nim_lk";
rev = finalAttrs.version;
hash = lib.fakeHash;
};
buildInputs = [ openssl ];
}) ./sbom.json
```
### Generating SBOMs {#generating-nim-sboms}
The [nim_lk](https://git.sr.ht/~ehmry/nim_lk) utility can generate SBOMs from [Nimble](https://github.com/nim-lang/nimble) package metadata.
See the [nim_lk documentation](https://git.sr.ht/~ehmry/nim_lk#nimble-to-cyclonedx-sbom) for more information.
## Overriding Nim packages {#nim-overrides}
The `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`:
```nix
pkgs.nitter.overrideNimAttrs {
# using a different source which has different dependencies from the standard package
src = pkgs.fetchFromGithub { /* … */ };
# new lock file generated from the source
lockFile = ./custom-lock.json;
}
```
## Lockfile dependency overrides {#nim-lock-overrides}
The `buildNimPackage` function matches the libraries specified by `lockFile` to attrset of override functions that are then applied to the package derivation.
The default overrides are maintained as the top-level `nimOverrides` attrset at `pkgs/top-level/nim-overrides.nix`.
For 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:
```nix
{ lib
/* … */
, SDL2
/* … */
}:
{
/* … */
sdl2 =
lockAttrs:
{ buildInputs ? [ ], ... }:
{
buildInputs = buildInputs ++ [ SDL2 ];
};
/* … */
}
```
The 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.
- 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.
- prevAttrs: the attrset produced by initial arguments to `buildNimPackage` and any preceding lockfile overlays.
### Overriding an Nim library override {#nim-lock-overrides-overrides}
The `nimOverrides` attrset makes it possible to modify overrides in a few different ways.
Override a package internal to its definition:
```nix
{ lib, buildNimPackage, nimOverrides, libressl }:
let
buildNimPackage' = buildNimPackage.override {
nimOverrides = nimOverrides.override { openssl = libressl; };
};
in buildNimPackage' (finalAttrs: {
pname = "foo";
# …
})
```
Override a package externally:
```nix
{ pkgs }: {
foo = pkgs.foo.override {
buildNimPackage = pkgs.buildNimPackage.override {
nimOverrides = pkgs.nimOverrides.override { openssl = libressl; };
};
};
}
```
|