blob: a0065f73314d03babeb1473e3145b8318583e95c (
plain)
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
|
{ lib, config, ... }:
with lib;
let
mergeFalseByDefault =
locs: defs:
if defs == [ ] then
abort "This case should never happen."
else if elem false (getValues defs) then
false
else
true;
kernelItem = types.submodule {
options = {
tristate = mkOption {
type = types.enum [
"y"
"m"
"n"
null
];
default = null;
internal = true;
visible = true;
description = ''
Use this field for tristate kernel options expecting a "y" or "m" or "n".
'';
};
freeform = mkOption {
type = types.nullOr types.str;
default = null;
example = ''MMC_BLOCK_MINORS.freeform = "32";'';
description = ''
Freeform description of a kernel configuration item value.
'';
};
optional = mkOption {
type = types.bool // {
merge = mergeFalseByDefault;
};
default = false;
description = ''
Whether option should generate a failure when unused.
Upon merging values, mandatory wins over optional.
'';
};
};
};
mkValue =
with lib;
val:
let
isNumber =
c:
elem c [
"0"
"1"
"2"
"3"
"4"
"5"
"6"
"7"
"8"
"9"
];
in
if val == "y" || val == "m" || val == "n" then
val
else if all isNumber (stringToCharacters val) then
val
else if substring 0 2 val == "0x" then
val
else
val; # FIXME: fix quoting one day
# generate nix intermediate kernel config file of the form
#
# VIRTIO_MMIO m
# VIRTIO_BLK y
# VIRTIO_CONSOLE n
# NET_9P_VIRTIO? y
# LOCALVERSION
#
# A line without a value means an empty string.
#
# Borrowed from copumpkin https://github.com/NixOS/nixpkgs/pull/12158
# returns a string, expr should be an attribute set
# Use mkValuePreprocess to preprocess option values, aka mark 'modules' as 'yes' or vice-versa
# use the identity if you don't want to override the configured values
generateNixKConf =
exprs:
let
mkConfigLine =
key: item:
let
val = if item.freeform != null then item.freeform else item.tristate;
in
optionalString (val != null)
"${key}${optionalString item.optional "?"}${optionalString (val != "") " ${mkValue val}"}\n";
mkConf = cfg: concatStrings (mapAttrsToList mkConfigLine cfg);
in
mkConf exprs;
in
{
options = {
intermediateNixConfig = mkOption {
readOnly = true;
type = types.lines;
example = ''
USB? y
DEBUG n
LOCALVERSION
'';
description = ''
The result of converting the structured kernel configuration in settings
to an intermediate string that can be parsed by generate-config.pl to
answer the kernel `make defconfig`.
'';
};
settings = mkOption {
type = types.attrsOf kernelItem;
example = literalExpression ''
with lib.kernel; {
"9P_NET" = yes;
USB = option yes;
MMC_BLOCK_MINORS = freeform "32";
}'';
description = ''
Structured kernel configuration.
'';
};
};
config = {
intermediateNixConfig = generateNixKConf config.settings;
};
}
|