Skip to content

Commit 918c1a9

Browse files
authored
Merge pull request #14489 from roberth/shell-a-la-carte
Infer devShell deps, provide smaller one
2 parents 091c0a9 + cb5b0c3 commit 918c1a9

File tree

10 files changed

+265
-91
lines changed

10 files changed

+265
-91
lines changed

doc/manual/package.nix

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ mkMesonDerivation (finalAttrs: {
5858
"man"
5959
];
6060

61-
# Hack for sake of the dev shell
62-
passthru.externalNativeBuildInputs = [
61+
nativeBuildInputs = [
62+
nix-cli
6363
meson
6464
ninja
6565
(lib.getBin lowdown-unsandboxed)
@@ -78,10 +78,6 @@ mkMesonDerivation (finalAttrs: {
7878
changelog-d
7979
];
8080

81-
nativeBuildInputs = finalAttrs.passthru.externalNativeBuildInputs ++ [
82-
nix-cli
83-
];
84-
8581
preConfigure = ''
8682
chmod u+w ./.version
8783
echo ${finalAttrs.version} > ./.version

meson.build

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,4 +60,9 @@ if get_option('unit-tests')
6060
subproject('libflake-tests')
6161
endif
6262
subproject('nix-functional-tests')
63-
subproject('json-schema-checks')
63+
if get_option('json-schema-checks')
64+
subproject('json-schema-checks')
65+
endif
66+
if get_option('kaitai-struct-checks')
67+
subproject('kaitai-struct-checks')
68+
endif

meson.options

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,17 @@ option(
2727
value : false,
2828
description : 'Build benchmarks (requires gbenchmark)',
2929
)
30+
31+
option(
32+
'kaitai-struct-checks',
33+
type : 'boolean',
34+
value : true,
35+
description : 'Check the Kaitai Struct specifications (requires Kaitai Struct)',
36+
)
37+
38+
option(
39+
'json-schema-checks',
40+
type : 'boolean',
41+
value : true,
42+
description : 'Check JSON schema validity of schemas and examples (requires jv)',
43+
)

packaging/dev-shell.nix

Lines changed: 203 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,118 @@
33
devFlake,
44
}:
55

6+
let
7+
# Some helper functions
8+
9+
/**
10+
Compute a filtered closure of build inputs.
11+
12+
Specifically, `buildInputsClosure cond startSet` computes the closure formed
13+
by recursive application of `p: filter cond p.buildInputs ++ filter cond p.propagatedBuildInputs`
14+
to `startSet`.
15+
16+
Example:
17+
```nix
18+
builtInputsClosure isInternal [ pkg1 pkg2 ]
19+
=> [ pkg1 pkg3 pkg2 pkg10 ]
20+
```
21+
22+
Note: order tbd
23+
24+
Note: `startSet` is *NOT* filtered.
25+
*/
26+
buildInputsClosureCond =
27+
cond: startSet:
28+
let
29+
closure = builtins.genericClosure {
30+
startSet = map (d: {
31+
key = d.drvPath;
32+
value = d;
33+
}) startSet;
34+
operator =
35+
d:
36+
let
37+
r =
38+
map
39+
(d': {
40+
key = d'.drvPath;
41+
value = d';
42+
})
43+
(
44+
lib.filter cond d.value.buildInputs or [ ] ++ lib.filter cond d.value.propagatedBuildInputs or [ ]
45+
);
46+
in
47+
r;
48+
};
49+
in
50+
map (item: item.value) closure;
51+
52+
/**
53+
`[ pkg1 pkg2 ]` -> `{ "...-pkg2.drv" = null; "...-pkg1.drv" = null }`
54+
55+
Note: fairly arbitrary order (hash based). Use for efficient set membership test only.
56+
*/
57+
byDrvPath =
58+
l:
59+
lib.listToAttrs (
60+
map (c: {
61+
name =
62+
# Just a lookup key
63+
builtins.unsafeDiscardStringContext c.drvPath;
64+
value = null;
65+
}) l
66+
);
67+
68+
/**
69+
Stable dedup.
70+
71+
Unlike `listToAttrs` -> `attrValues`, this preserves the input ordering,
72+
which is more predictable ("deterministic") than e.g. sorting store paths,
73+
whose hashes affect the ordering on every change.
74+
*/
75+
# TODO: add to Nixpkgs lib, refer from uniqueStrings
76+
dedupByString =
77+
key: l:
78+
let
79+
r =
80+
lib.foldl'
81+
(
82+
a@{ list, set }:
83+
elem:
84+
let
85+
k = builtins.unsafeDiscardStringContext (key elem);
86+
in
87+
if set ? ${k} then
88+
a
89+
else
90+
let
91+
# Note: O(n²) copying. Use linkedLists to concat them in one go at the end.
92+
# https://github.com/NixOS/nixpkgs/pull/452088
93+
newList = [ elem ] ++ list;
94+
newSet = set // {
95+
${k} = null;
96+
};
97+
in
98+
builtins.seq newList builtins.seq newSet {
99+
list = newList;
100+
set = newSet;
101+
}
102+
)
103+
{
104+
list = [ ];
105+
set = { };
106+
}
107+
l;
108+
in
109+
r.list;
110+
111+
in
112+
6113
{ pkgs }:
7114

115+
# TODO: don't use nix-util for this?
8116
pkgs.nixComponents2.nix-util.overrideAttrs (
9-
attrs:
117+
finalAttrs: prevAttrs:
10118

11119
let
12120
stdenv = pkgs.nixDependencies2.stdenv;
@@ -21,13 +129,89 @@ pkgs.nixComponents2.nix-util.overrideAttrs (
21129
"-D${prefix}:${rest}";
22130
havePerl = stdenv.buildPlatform == stdenv.hostPlatform && stdenv.hostPlatform.isUnix;
23131
ignoreCrossFile = flags: builtins.filter (flag: !(lib.strings.hasInfix "cross-file" flag)) flags;
132+
133+
activeComponents = buildInputsClosureCond isInternal (
134+
lib.attrValues (finalAttrs.passthru.config.getComponents allComponents)
135+
);
136+
137+
allComponents = lib.filterAttrs (k: v: lib.isDerivation v) pkgs.nixComponents2;
138+
internalDrvs = byDrvPath (
139+
# Drop the attr names (not present in buildInputs anyway)
140+
lib.attrValues allComponents
141+
++ lib.concatMap (c: lib.attrValues c.tests or { }) (lib.attrValues allComponents)
142+
);
143+
144+
isInternal =
145+
dep: internalDrvs ? ${builtins.unsafeDiscardStringContext dep.drvPath or "_non-existent_"};
146+
24147
in
25148
{
26-
pname = "shell-for-" + attrs.pname;
149+
pname = "shell-for-nix";
150+
151+
passthru = {
152+
inherit activeComponents;
153+
154+
# We use this attribute to store non-derivation values like functions and
155+
# perhaps other things that are primarily for overriding and not the shell.
156+
config = {
157+
# Default getComponents
158+
getComponents =
159+
c:
160+
builtins.removeAttrs c (
161+
lib.optionals (!havePerl) [ "nix-perl-bindings" ]
162+
++ lib.optionals (!buildCanExecuteHost) [ "nix-manual" ]
163+
);
164+
};
165+
166+
/**
167+
Produce a devShell for a given set of nix components
168+
169+
Example:
170+
171+
```nix
172+
shell.withActiveComponents (c: {
173+
inherit (c) nix-util;
174+
})
175+
```
176+
*/
177+
withActiveComponents =
178+
f2:
179+
finalAttrs.finalPackage.overrideAttrs (
180+
finalAttrs: prevAttrs: {
181+
passthru = prevAttrs.passthru // {
182+
config = prevAttrs.passthru.config // {
183+
getComponents = f2;
184+
};
185+
};
186+
}
187+
);
188+
189+
small =
190+
(finalAttrs.finalPackage.withActiveComponents (c: {
191+
inherit (c)
192+
nix-cli
193+
nix-util-tests
194+
nix-store-tests
195+
nix-expr-tests
196+
nix-fetchers-tests
197+
nix-flake-tests
198+
nix-functional-tests
199+
# Currently required
200+
nix-perl-bindings
201+
;
202+
})).overrideAttrs
203+
(o: {
204+
mesonFlags = o.mesonFlags ++ [
205+
# TODO: infer from activeComponents or vice versa
206+
"-Dkaitai-struct-checks=false"
207+
"-Djson-schema-checks=false"
208+
];
209+
});
210+
};
27211

28212
# Remove the version suffix to avoid unnecessary attempts to substitute in nix develop
29213
version = lib.fileContents ../.version;
30-
name = attrs.pname;
214+
name = finalAttrs.pname;
31215

32216
installFlags = "sysconfdir=$(out)/etc";
33217
shellHook = ''
@@ -98,17 +282,9 @@ pkgs.nixComponents2.nix-util.overrideAttrs (
98282
nativeBuildInputs =
99283
let
100284
inputs =
101-
attrs.nativeBuildInputs or [ ]
102-
++ pkgs.nixComponents2.nix-util.nativeBuildInputs
103-
++ pkgs.nixComponents2.nix-store.nativeBuildInputs
104-
++ pkgs.nixComponents2.nix-fetchers.nativeBuildInputs
105-
++ pkgs.nixComponents2.nix-expr.nativeBuildInputs
106-
++ lib.optionals havePerl pkgs.nixComponents2.nix-perl-bindings.nativeBuildInputs
107-
++ lib.optionals buildCanExecuteHost pkgs.nixComponents2.nix-manual.externalNativeBuildInputs
108-
++ pkgs.nixComponents2.nix-internal-api-docs.nativeBuildInputs
109-
++ pkgs.nixComponents2.nix-external-api-docs.nativeBuildInputs
110-
++ pkgs.nixComponents2.nix-functional-tests.externalNativeBuildInputs
111-
++ pkgs.nixComponents2.nix-json-schema-checks.externalNativeBuildInputs
285+
dedupByString (v: "${v}") (
286+
lib.filter (x: !isInternal x) (lib.lists.concatMap (c: c.nativeBuildInputs) activeComponents)
287+
)
112288
++ lib.optional (
113289
!buildCanExecuteHost
114290
# Hack around https://github.com/nixos/nixpkgs/commit/bf7ad8cfbfa102a90463433e2c5027573b462479
@@ -117,9 +293,7 @@ pkgs.nixComponents2.nix-util.overrideAttrs (
117293
&& lib.meta.availableOn stdenv.buildPlatform (stdenv.hostPlatform.emulator pkgs.buildPackages)
118294
) pkgs.buildPackages.mesonEmulatorHook
119295
++ [
120-
pkgs.buildPackages.cmake
121296
pkgs.buildPackages.gnused
122-
pkgs.buildPackages.changelog-d
123297
modular.pre-commit.settings.package
124298
(pkgs.writeScriptBin "pre-commit-hooks-install" modular.pre-commit.settings.installationScript)
125299
pkgs.buildPackages.nixfmt-rfc-style
@@ -136,18 +310,22 @@ pkgs.nixComponents2.nix-util.overrideAttrs (
136310
# from making its way into NIX_CFLAGS_COMPILE.
137311
lib.filter (p: !lib.hasInfix "separate-debug-info" p) inputs;
138312

313+
propagatedNativeBuildInputs = dedupByString (v: "${v}") (
314+
lib.filter (x: !isInternal x) (
315+
lib.lists.concatMap (c: c.propagatedNativeBuildInputs) activeComponents
316+
)
317+
);
318+
139319
buildInputs = [
140320
pkgs.gbenchmark
141321
]
142-
++ attrs.buildInputs or [ ]
143-
++ pkgs.nixComponents2.nix-util.buildInputs
144-
++ pkgs.nixComponents2.nix-store.buildInputs
145-
++ pkgs.nixComponents2.nix-store-tests.externalBuildInputs
146-
++ pkgs.nixComponents2.nix-fetchers.buildInputs
147-
++ pkgs.nixComponents2.nix-expr.buildInputs
148-
++ pkgs.nixComponents2.nix-expr.externalPropagatedBuildInputs
149-
++ pkgs.nixComponents2.nix-cmd.buildInputs
150-
++ lib.optionals havePerl pkgs.nixComponents2.nix-perl-bindings.externalBuildInputs
322+
++ dedupByString (v: "${v}") (
323+
lib.filter (x: !isInternal x) (lib.lists.concatMap (c: c.buildInputs) activeComponents)
324+
)
151325
++ lib.optional havePerl pkgs.perl;
326+
327+
propagatedBuildInputs = dedupByString (v: "${v}") (
328+
lib.filter (x: !isInternal x) (lib.lists.concatMap (c: c.propagatedBuildInputs) activeComponents)
329+
);
152330
}
153331
)

src/json-schema-checks/package.nix

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,11 @@ mkMesonDerivation (finalAttrs: {
3434

3535
outputs = [ "out" ];
3636

37-
passthru.externalNativeBuildInputs = [
38-
jsonschema
39-
];
40-
4137
nativeBuildInputs = [
4238
meson
4339
ninja
44-
]
45-
++ finalAttrs.passthru.externalNativeBuildInputs;
40+
jsonschema
41+
];
4642

4743
doCheck = true;
4844

src/kaitai-struct-checks/package.nix

Lines changed: 9 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,15 @@ mkMesonDerivation (finalAttrs: {
3737

3838
outputs = [ "out" ];
3939

40-
passthru.externalNativeBuildInputs = [
40+
buildInputs = [
41+
gtest
42+
kaitai-struct-cpp-stl-runtime
43+
];
44+
45+
nativeBuildInputs = [
46+
meson
47+
ninja
48+
pkg-config
4149
# This can go away when we bump up to 25.11
4250
(kaitai-struct-compiler.overrideAttrs (finalAttrs: {
4351
version = "0.11";
@@ -48,20 +56,6 @@ mkMesonDerivation (finalAttrs: {
4856
}))
4957
];
5058

51-
passthru.externalBuildInputs = [
52-
gtest
53-
kaitai-struct-cpp-stl-runtime
54-
];
55-
56-
buildInputs = finalAttrs.passthru.externalBuildInputs;
57-
58-
nativeBuildInputs = [
59-
meson
60-
ninja
61-
pkg-config
62-
]
63-
++ finalAttrs.passthru.externalNativeBuildInputs;
64-
6559
doCheck = true;
6660

6761
mesonCheckFlags = [ "--print-errorlogs" ];

src/libexpr/package.nix

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,11 +70,6 @@ mkMesonLibrary (finalAttrs: {
7070
nix-util
7171
nix-store
7272
nix-fetchers
73-
]
74-
++ finalAttrs.passthru.externalPropagatedBuildInputs;
75-
76-
# Hack for sake of the dev shell
77-
passthru.externalPropagatedBuildInputs = [
7873
boost
7974
nlohmann_json
8075
]

0 commit comments

Comments
 (0)