at 16.09-beta 141 lines 4.6 kB view raw
1# This script runs `make config' to generate a Linux kernel 2# configuration file. For each question (i.e. kernel configuration 3# option), unless an override is provided, it answers "m" if possible, 4# and otherwise uses the default answer (as determined by the default 5# config for the architecture). Overrides are read from the file 6# $KERNEL_CONFIG, which on each line contains an option name and an 7# answer, e.g. "EXT2_FS_POSIX_ACL y". The script warns about ignored 8# options in $KERNEL_CONFIG, and barfs if `make config' selects 9# another answer for an option than the one provided in 10# $KERNEL_CONFIG. 11 12use strict; 13use IPC::Open2; 14use Cwd; 15 16my $wd = getcwd; 17 18my $debug = $ENV{'DEBUG'}; 19my $autoModules = $ENV{'AUTO_MODULES'}; 20 21$SIG{PIPE} = 'IGNORE'; 22 23# Read the answers. 24my %answers; 25my %requiredAnswers; 26open ANSWERS, "<$ENV{KERNEL_CONFIG}" or die; 27while (<ANSWERS>) { 28 chomp; 29 s/#.*//; 30 if (/^\s*([A-Za-z0-9_]+)(\?)?\s+(\S+)\s*$/) { 31 $answers{$1} = $3; 32 $requiredAnswers{$1} = !(defined $2); 33 } elsif (!/^\s*$/) { 34 die "invalid config line: $_"; 35 } 36} 37close ANSWERS; 38 39sub runConfig { 40 41 # Run `make config'. 42 my $pid = open2(\*IN, \*OUT, "make -C $ENV{SRC} O=$wd config SHELL=bash ARCH=$ENV{ARCH}"); 43 44 # Parse the output, look for questions and then send an 45 # appropriate answer. 46 my $line = ""; my $s; 47 my %choices = (); 48 49 my ($prevQuestion, $prevName); 50 51 while (!eof IN) { 52 read IN, $s, 1 or next; 53 $line .= $s; 54 55 #print STDERR "LINE: $line\n"; 56 57 if ($s eq "\n") { 58 print STDERR "GOT: $line" if $debug; 59 60 # Remember choice alternatives ("> 1. bla (FOO)" or " 2. bla (BAR) (NEW)"). 61 if ($line =~ /^\s*>?\s*(\d+)\.\s+.*?\(([A-Za-z0-9_]+)\)(?:\s+\(NEW\))?\s*$/) { 62 $choices{$2} = $1; 63 } 64 65 $line = ""; 66 } 67 68 elsif ($line =~ /###$/) { 69 # The config program is waiting for an answer. 70 71 # Is this a regular question? ("bla bla (OPTION_NAME) [Y/n/m/...] ") 72 if ($line =~ /(.*) \(([A-Za-z0-9_]+)\) \[(.*)\].*###$/) { 73 my $question = $1; my $name = $2; my $alts = $3; 74 my $answer = ""; 75 # Build everything as a module if possible. 76 $answer = "m" if $autoModules && $alts =~ /\/m/; 77 $answer = $answers{$name} if defined $answers{$name}; 78 print STDERR "QUESTION: $question, NAME: $name, ALTS: $alts, ANSWER: $answer\n" if $debug; 79 print OUT "$answer\n"; 80 die "repeated question: $question" if $prevQuestion && $prevQuestion eq $question && $name eq $prevName; 81 $prevQuestion = $question; 82 $prevName = $name; 83 } 84 85 # Is this a choice? ("choice[1-N]: ") 86 elsif ($line =~ /choice\[(.*)\]: ###$/) { 87 my $answer = ""; 88 foreach my $name (keys %choices) { 89 $answer = $choices{$name} if ($answers{$name} || "") eq "y"; 90 } 91 print STDERR "CHOICE: $1, ANSWER: $answer\n" if $debug; 92 print OUT "$answer\n" if $1 =~ /-/; 93 } 94 95 # Some questions lack the option name ("bla bla [Y/n/m/...] "). 96 elsif ($line =~ /(.*) \[(.*)\] ###$/) { 97 print OUT "\n"; 98 } 99 100 else { 101 warn "don't know how to answer this question: $line\n"; 102 print OUT "\n"; 103 } 104 105 $line = ""; 106 %choices = (); 107 } 108 } 109 110 close IN; 111 waitpid $pid, 0; 112} 113 114# Run `make config' several times to converge on the desired result. 115# (Some options may only become available after other options are 116# set in a previous run.) 117runConfig; 118runConfig; 119 120# Read the final .config file and check that our answers are in 121# there. `make config' often overrides answers if later questions 122# cause options to be selected. 123my %config; 124open CONFIG, "<.config" or die; 125while (<CONFIG>) { 126 chomp; 127 if (/^CONFIG_([A-Za-z0-9_]+)=(.*)$/) { 128 $config{$1} = $2; 129 } elsif (/^# CONFIG_([A-Za-z0-9_]+) is not set$/) { 130 $config{$1} = "n"; 131 } 132} 133close CONFIG; 134 135foreach my $name (sort (keys %answers)) { 136 my $f = $requiredAnswers{$name} && $ENV{'ignoreConfigErrors'} ne "1" 137 ? sub { die "error: " . $_[0]; } : sub { warn "warning: " . $_[0]; }; 138 &$f("unused option: $name\n") unless defined $config{$name}; 139 &$f("option not set correctly: $name\n") 140 if $config{$name} && $config{$name} ne $answers{$name}; 141}