diff options
author | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2009-12-12 13:51:07 +0000 |
---|---|---|
committer | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2009-12-12 13:51:07 +0000 |
commit | 03e45e0cb4c56ec37088a7bc64001da02727dde6 (patch) | |
tree | fc6674d69e8e7cff6bdd9f8966905b127ac2709a /pkgs/os-specific/linux/kernel/generate-config.pl | |
parent | adbaa14548313997bf8c74a40358ea4a14e656d1 (diff) | |
download | nixpkgs-03e45e0cb4c56ec37088a7bc64001da02727dde6.tar nixpkgs-03e45e0cb4c56ec37088a7bc64001da02727dde6.tar.gz nixpkgs-03e45e0cb4c56ec37088a7bc64001da02727dde6.tar.bz2 nixpkgs-03e45e0cb4c56ec37088a7bc64001da02727dde6.tar.lz nixpkgs-03e45e0cb4c56ec37088a7bc64001da02727dde6.tar.xz nixpkgs-03e45e0cb4c56ec37088a7bc64001da02727dde6.tar.zst nixpkgs-03e45e0cb4c56ec37088a7bc64001da02727dde6.zip |
* Added a script to generate the kernel configuration.
`generate-config.pl' runs `make config' to generate a Linux kernel configuration file. For each question (i.e. kernel configuration option), unless an override is provided, it answers "m" if possible, and otherwise uses the default answer (as determined by the default config for the architecture). This is safer than allmodconfig, which answers "y" everywhere it can't answer "m" and thus ends up enabling a lot of experimental or debug options. (For this reason, a configuration generated by allmodconfig must be carefully checked with every new release to ensure that nothing dangerous is enabled. The default config should be safer wrt new kernel releases.) Overrides are specified in the `config' argument to generic.nix, which is a string that contains lines such as `EXT2_FS_POSIX_ACL y'. The script warns about ignored options, and aborts if `make config' selects an answer inconsistent with the one in `config'. This allows us to be sure that `make config' doesn't silently override our configuration values (e.g., depending on other options, it will set FB_TILEBLITTING to "y" even if we want it to be "n"). svn path=/nixpkgs/branches/kernel-config/; revision=18910
Diffstat (limited to 'pkgs/os-specific/linux/kernel/generate-config.pl')
-rw-r--r-- | pkgs/os-specific/linux/kernel/generate-config.pl | 130 |
1 files changed, 130 insertions, 0 deletions
diff --git a/pkgs/os-specific/linux/kernel/generate-config.pl b/pkgs/os-specific/linux/kernel/generate-config.pl new file mode 100644 index 00000000000..d421707727c --- /dev/null +++ b/pkgs/os-specific/linux/kernel/generate-config.pl @@ -0,0 +1,130 @@ +# This script runs `make config' to generate a Linux kernel +# configuration file. For each question (i.e. kernel configuration +# option), unless an override is provided, it answers "m" if possible, +# and otherwise uses the default answer (as determined by the default +# config for the architecture). Overrides are read from the file +# $KERNEL_CONFIG, which on each line contains an option name and an +# answer, e.g. "EXT2_FS_POSIX_ACL y". The script warns about ignored +# options in $KERNEL_CONFIG, and barfs if `make config' selects +# another answer for an option than the one provided in +# $KERNEL_CONFIG. + +use strict; +use IPC::Open2; + +my $debug = $ENV{'DEBUG'}; + +$SIG{PIPE} = 'IGNORE'; + +# Read the answers. +my %answers; +open ANSWERS, "<$ENV{KERNEL_CONFIG}" or die; +while (<ANSWERS>) { + chomp; + s/#.*//; + my ($name, $value) = split / /; + $answers{$name} = $value if $name; +} +close ANSWERS; + +sub runConfig { + + # Run `make config'. + my $pid = open2(\*IN, \*OUT, "make config SHELL=bash ARCH=$ENV{ARCH}"); + + # Parse the output, look for questions and then send an + # appropriate answer. + my $line = ""; my $s; + my %choices = (); + + my ($prevQuestion, $prevName); + + while (!eof IN) { + read IN, $s, 1 or next; + $line .= $s; + + #print STDERR "LINE: $line\n"; + + if ($s eq "\n") { + print STDERR "GOT: $line" if $debug; + + # Remember choice alternatives ("> 1. bla (FOO)" or " 2. bla (BAR)"). + if ($line =~ /^\s*>?\s*(\d+)\.\s+.*\(([A-Za-z0-9_]+)\)$/) { + $choices{$2} = $1; + } + + $line = ""; + } + + elsif ($line =~ /###$/) { + # The config program is waiting for an answer. + + # Is this a regular question? ("bla bla (OPTION_NAME) [Y/n/m/...] ") + if ($line =~ /(.*) \(([A-Za-z0-9_]+)\) \[(.*)\].*###$/) { + my $question = $1; my $name = $2; my $alts = $3; + my $answer = ""; + # Build everything as a module if possible. + $answer = "m" if $alts =~ /\/m/; + $answer = $answers{$name} if defined $answers{$name}; + print STDERR "QUESTION: $question, NAME: $name, ALTS: $alts, ANSWER: $answer\n" if $debug; + print OUT "$answer\n"; + die "repeated question: $question" if $prevQuestion && $prevQuestion eq $question && $name eq $prevName; + $prevQuestion = $question; + $prevName = $name; + } + + # Is this a choice? ("choice[1-N]: ") + elsif ($line =~ /choice\[(.*)\]: ###$/) { + my $answer = ""; + foreach my $name (keys %choices) { + $answer = $choices{$name} if ($answers{$name} || "") eq "y"; + } + print STDERR "CHOICE: $1, ANSWER: $answer\n" if $debug; + print OUT "$answer\n" if $1 =~ /-/; + } + + # Some questions lack the option name ("bla bla [Y/n/m/...] "). + elsif ($line =~ /(.*) \[(.*)\] ###$/) { + print OUT "\n"; + } + + else { + die "don't know how to answer this question: $line\n"; + } + + $line = ""; + %choices = (); + } + } + + close IN; + waitpid $pid, 0; +} + +# Run `make config' several times to converge on the desired result. +# (Some options may only become available after other options are +# set in a previous run.) +runConfig; +runConfig; + +# Read the final .config file and check that our answers are in +# there. `make config' often overrides answers if later questions +# cause options to be selected. +my %config; +open CONFIG, "<.config" or die; +while (<CONFIG>) { + chomp; + if (/^CONFIG_([A-Za-z0-9_]+)=(.*)$/) { + $config{$1} = $2; + } elsif (/^# CONFIG_([A-Za-z0-9_]+) is not set$/) { + $config{$1} = "n"; + } +} +close CONFIG; + +foreach my $name (sort (keys %answers)) { + print STDERR "unused option: $name\n" + unless defined $config{$name}; + die "option not set correctly: $name\n" + if $config{$name} && $config{$name} ne $answers{$name}; +} |