Something went wrong. Try again.
What happens if I push all of nixpkgs
Something went wrong. Try again.
5.8 kB · 160 lines
Perl
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161# 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;use Cwd;
# exported via nixmy $debug = $ENV{'DEBUG'};my $autoModules = $ENV{'AUTO_MODULES'};my $preferBuiltin = $ENV{'PREFER_BUILTIN'};my $ignoreConfigErrors = $ENV{'ignoreConfigErrors'};my $buildRoot = $ENV{'BUILD_ROOT'};my $makeFlags = $ENV{'MAKE_FLAGS'};$SIG{PIPE} = 'IGNORE';
# Read the answers.my %answers;my %requiredAnswers;open ANSWERS, "<$ENV{KERNEL_CONFIG}" or die "Could not open answer file";while (<ANSWERS>) { chomp; s/#.*//; if (/^\s*([A-Za-z0-9_]+)(\?)?\s+(.*\S)\s*$/) { $answers{$1} = $3; $requiredAnswers{$1} = !(defined $2); } elsif (!/^\s*$/) { die "invalid config line: $_"; }}close ANSWERS;
sub runConfig {
# Run `make config'. # # We have to pass through the target toolchain, because `make config` checks them for versions. This is # required to get clang LTO working, among other things. my $pid = open2(\*IN, \*OUT, "make -C $ENV{SRC} O=$buildRoot config" . " SHELL=bash ARCH=$ENV{ARCH} CROSS_COMPILE=$ENV{CROSS_COMPILE}" . " $makeFlags");
# 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) (NEW)"). if ($line =~ /^\s*>?\s*(\d+)\.\s+.*?\(([A-Za-z0-9_]+)\)(?:\s+\(NEW\))?\s*$/) { $choices{$2} = $1; } else { # The list of choices has ended without us being # asked. This happens for options where only one value # is valid, for instance. The results can foul up # later options, so forget about it. %choices = (); }
$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 $autoModules && $alts =~ qr{\A(\w/)+m/(\w/)*\?\z} && !($preferBuiltin && $alts =~ /Y/); $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 { warn "don't know how to answer this question: $line\n"; print OUT "\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, "<$buildRoot/.config" or die "Could not read .config";while (<CONFIG>) { chomp; if (/^CONFIG_([A-Za-z0-9_]+)="(.*)"$/) { # String options have double quotes, e.g. 'CONFIG_NLS_DEFAULT="utf8"' and allow escaping. ($config{$1} = $2) =~ s/\\([\\"])/$1/g; } elsif (/^CONFIG_([A-Za-z0-9_]+)=(.*)$/) { $config{$1} = $2; } elsif (/^# CONFIG_([A-Za-z0-9_]+) is not set$/) { $config{$1} = "n"; }}close CONFIG;
my $ret = 0;foreach my $name (sort (keys %answers)) { my $f = $requiredAnswers{$name} && $ignoreConfigErrors ne "1" ? sub { warn "error: " . $_[0]; $ret = -1; } : sub { warn "warning: " . $_[0]; }; &$f("unused option: $name\n") unless defined $config{$name}; &$f("option not set correctly: $name (wanted '$answers{$name}', got '$config{$name}')\n") if $config{$name} && $config{$name} ne $answers{$name};}exit $ret;