at master 3.5 kB view raw
1{ lib, config, ... }: 2 3with lib; 4let 5 mergeFalseByDefault = 6 locs: defs: 7 if defs == [ ] then 8 abort "This case should never happen." 9 else if any (x: x == false) (getValues defs) then 10 false 11 else 12 true; 13 14 kernelItem = types.submodule { 15 options = { 16 tristate = mkOption { 17 type = types.enum [ 18 "y" 19 "m" 20 "n" 21 null 22 ]; 23 default = null; 24 internal = true; 25 visible = true; 26 description = '' 27 Use this field for tristate kernel options expecting a "y" or "m" or "n". 28 ''; 29 }; 30 31 freeform = mkOption { 32 type = types.nullOr types.str // { 33 merge = mergeEqualOption; 34 }; 35 default = null; 36 example = ''MMC_BLOCK_MINORS.freeform = "32";''; 37 description = '' 38 Freeform description of a kernel configuration item value. 39 ''; 40 }; 41 42 optional = mkOption { 43 type = types.bool // { 44 merge = mergeFalseByDefault; 45 }; 46 default = false; 47 description = '' 48 Whether option should generate a failure when unused. 49 Upon merging values, mandatory wins over optional. 50 ''; 51 }; 52 }; 53 }; 54 55 mkValue = 56 with lib; 57 val: 58 let 59 isNumber = 60 c: 61 elem c [ 62 "0" 63 "1" 64 "2" 65 "3" 66 "4" 67 "5" 68 "6" 69 "7" 70 "8" 71 "9" 72 ]; 73 74 in 75 if (val == "") then 76 "\"\"" 77 else if val == "y" || val == "m" || val == "n" then 78 val 79 else if all isNumber (stringToCharacters val) then 80 val 81 else if substring 0 2 val == "0x" then 82 val 83 else 84 val; # FIXME: fix quoting one day 85 86 # generate nix intermediate kernel config file of the form 87 # 88 # VIRTIO_MMIO m 89 # VIRTIO_BLK y 90 # VIRTIO_CONSOLE n 91 # NET_9P_VIRTIO? y 92 # 93 # Borrowed from copumpkin https://github.com/NixOS/nixpkgs/pull/12158 94 # returns a string, expr should be an attribute set 95 # Use mkValuePreprocess to preprocess option values, aka mark 'modules' as 'yes' or vice-versa 96 # use the identity if you don't want to override the configured values 97 generateNixKConf = 98 exprs: 99 let 100 mkConfigLine = 101 key: item: 102 let 103 val = if item.freeform != null then item.freeform else item.tristate; 104 in 105 optionalString (val != null) ( 106 if (item.optional) then "${key}? ${mkValue val}\n" else "${key} ${mkValue val}\n" 107 ); 108 109 mkConf = cfg: concatStrings (mapAttrsToList mkConfigLine cfg); 110 in 111 mkConf exprs; 112 113in 114{ 115 116 options = { 117 118 intermediateNixConfig = mkOption { 119 readOnly = true; 120 type = types.lines; 121 example = '' 122 USB? y 123 DEBUG n 124 ''; 125 description = '' 126 The result of converting the structured kernel configuration in settings 127 to an intermediate string that can be parsed by generate-config.pl to 128 answer the kernel `make defconfig`. 129 ''; 130 }; 131 132 settings = mkOption { 133 type = types.attrsOf kernelItem; 134 example = literalExpression '' 135 with lib.kernel; { 136 "9P_NET" = yes; 137 USB = option yes; 138 MMC_BLOCK_MINORS = freeform "32"; 139 }''; 140 description = '' 141 Structured kernel configuration. 142 ''; 143 }; 144 }; 145 146 config = { 147 intermediateNixConfig = generateNixKConf config.settings; 148 }; 149}