summary refs log tree commit diff
path: root/pkgs/os-specific/linux/kernel/generate-config.pl
diff options
context:
space:
mode:
authorEelco Dolstra <eelco.dolstra@logicblox.com>2009-12-12 13:51:07 +0000
committerEelco Dolstra <eelco.dolstra@logicblox.com>2009-12-12 13:51:07 +0000
commit03e45e0cb4c56ec37088a7bc64001da02727dde6 (patch)
treefc6674d69e8e7cff6bdd9f8966905b127ac2709a /pkgs/os-specific/linux/kernel/generate-config.pl
parentadbaa14548313997bf8c74a40358ea4a14e656d1 (diff)
downloadnixpkgs-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.pl130
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};
+}