linux: translate config to structured config

Instead of using a string to describe kernel config, use a nix
attribute set, then converted to a string.
- allows to override the config, aka convert 'yes' into 'modules' or
vice-versa
- while for now merging different configs is still crude (last spec wins),
at least there should be only one CONFIG_XYZ value compared to the current string
config where the first defined would be used and others ignored.

[initial idea by copumpkin in 2016, a major rebase to 2018 by teto]
This commit is contained in:
Dan Peebles 2016-01-05 09:22:43 -05:00 committed by Tuomas Tynkkynen
parent bae87d5042
commit ff9999ad1b
4 changed files with 739 additions and 697 deletions

57
lib/kernel.nix Normal file
View file

@ -0,0 +1,57 @@
{ lib
# we pass the kernel version here to keep a nice syntax `whenOlder "4.13"`
# kernelVersion, e.g., config.boot.kernelPackages.version
, version
, mkValuePreprocess ? null
}:
with lib;
rec {
# Common patterns
when = cond: opt: if cond then opt else null;
whenAtLeast = ver: when (versionAtLeast version ver);
whenOlder = ver: when (versionOlder version ver);
whenBetween = verLow: verHigh: when (versionAtLeast version verLow && versionOlder version verHigh);
# Keeping these around in case we decide to change this horrible implementation :)
option = x: if x == null then null else "?${x}";
yes = "y";
no = "n";
module = "m";
mkValue = val:
let
isNumber = c: elem c ["0" "1" "2" "3" "4" "5" "6" "7" "8" "9"];
in
if val == "" then "\"\""
else if val == yes || val == module || val == no 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
#
# Use mkValuePreprocess to preprocess option values, aka mark 'modules' as
# 'yes' or vice-versa
# Borrowed from copumpkin https://github.com/NixOS/nixpkgs/pull/12158
# returns a string, expr should be an attribute set
generateNixKConf = exprs: mkValuePreprocess:
let
mkConfigLine = key: rawval:
let
val = if builtins.isFunction mkValuePreprocess then mkValuePreprocess rawval else rawval;
in
if val == null
then ""
else if hasPrefix "?" val
then "${key}? ${mkValue (removePrefix "?" val)}\n"
else "${key} ${mkValue val}\n";
mkConf = cfg: concatStrings (mapAttrsToList mkConfigLine cfg);
in mkConf exprs;
}

File diff suppressed because it is too large Load diff

View file

@ -15,9 +15,12 @@
, # Allows overriding the default defconfig
defconfig ? null
, # Overrides to the kernel config.
, # Legacy overrides to the intermediate kernel config, as string
extraConfig ? ""
, # kernel intermediate config overrides, as a set
structuredExtraConfig ? {}
, # The version number used for the module directory
modDirVersion ? version
@ -42,6 +45,7 @@
, preferBuiltin ? hostPlatform.platform.kernelPreferBuiltin or false
, kernelArch ? hostPlatform.platform.kernelArch
, mkValueOverride ? null
, ...
} @ args:
@ -59,8 +63,9 @@ let
netfilterRPFilter = true;
} // features) kernelPatches;
config = import ./common-config.nix {
inherit stdenv version ;
intermediateNixConfig = import ./common-config.nix {
inherit stdenv version structuredExtraConfig mkValueOverride;
# append extraConfig for backwards compatibility but also means the user can't override the kernelExtraConfig part
extraConfig = extraConfig + lib.optionalString (hostPlatform.platform ? kernelExtraConfig) hostPlatform.platform.kernelExtraConfig;
@ -79,7 +84,7 @@ let
generateConfig = ./generate-config.pl;
kernelConfig = kernelConfigFun config;
kernelConfig = kernelConfigFun intermediateNixConfig;
passAsFile = [ "kernelConfig" ];
depsBuildBuild = [ buildPackages.stdenv.cc ];

View file

@ -24,7 +24,7 @@ in {
modDirVersion ? version,
# The kernel source (tarball, git checkout, etc.)
src,
# Any patches
# a list of { name=..., patch=..., extraConfig=...} patches
kernelPatches ? [],
# The kernel .config file
configfile,