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