diff options
Diffstat (limited to 'v4l/scripts/make_kconfig.pl')
-rwxr-xr-x | v4l/scripts/make_kconfig.pl | 393 |
1 files changed, 359 insertions, 34 deletions
diff --git a/v4l/scripts/make_kconfig.pl b/v4l/scripts/make_kconfig.pl index b1d6f5d53..d5b34b36c 100755 --- a/v4l/scripts/make_kconfig.pl +++ b/v4l/scripts/make_kconfig.pl @@ -4,20 +4,156 @@ use FileHandle; my %depend = (); my %minver = (); my %config = (); +my %intopt = (); +my %hexopt = (); +my %tristate = (); +my %kernopts = (); +my %depmods = (); my $version, $level, $sublevel; +my $kernel=shift; +my $force_kconfig=shift; + +#!/usr/bin/perl +use FileHandle; + +########################################################### +# Checks config.h and autoconf.h for current kernel defines +sub process_config ($) +{ + my $filename = shift; + my $in = new FileHandle; + + open $in,"$kernel/include/$filename" or die "File not found: $kernel/include/$filename"; + while (<$in>) { + if (m|\#include\s+\<(.*)\>|) { + process_config ($1); + next; + } + if (m/\#define\s+CONFIG_([^ ]*)_ON_SMP\s+(.*)\n/) { + my $key=$1; + my $value=$2; +# printf "defined $key as $value\n"; + if ( $value == 1 ) { + $value='y'; + } + $kernopts{$key}=$value; + next; + } + if (m/\#define\s+CONFIG_([^ ]*)_MODULE\s+(.*)\n/) { + my $key=$1; + my $value=$2; +# printf "defined $key as $value\n"; + if ( $value == 1 ) { + $value='m'; + } + $kernopts{$key}=$value; + next; + } + if (m/\#define\s+CONFIG_([^ ]*)\s+(.*)\n/) { + my $key=$1; + my $value=$2; +# printf "defined $key as $value\n"; + if ( $value == 1 ) { + $value='y'; + } + $kernopts{$key}=$value; + next; + } + if (m/\#undef\s+CONFIG_([^ ]*)\n/) { +# printf "undefined $1\n"; + $kernopts{$1}='n'; + next; + } + } + + close $in; +} + +sub add_bool($) +{ + my $arg=shift; + + exists $config{$arg} or die "Adding unknown boolean '$arg'"; + $tristate{$arg}="bool"; +# printf "Boolean:%s\n",$arg; + + $kernopts{$arg}='y'; +} + +sub add_tristate($) +{ + my $arg=shift; + + exists $config{$arg} or die "Adding unknown tristate '$arg'"; + $tristate{$arg}="tristate"; + + $kernopts{$arg}='m'; +} + +sub add_int($) +{ + my $arg=shift; + + exists $config{$arg} or die "Adding unknown int '$arg'"; + $intopt{$arg} = 0; +} + +sub add_hex($) +{ + my $arg=shift; + + exists $config{$arg} or die "Adding unknown hex '$arg'"; + $hexopt{$arg} = 0; +} + +sub set_int_value($$) +{ + my $key = shift; + my $val = shift; + + exists $intopt{$key} or die "Default for unknown int option '$key'"; + $intopt{$key} = $val; +} + +sub set_hex_value($$) +{ + my $key = shift; + my $val = shift; + + exists $hexopt{$key} or die "Default for unknown hex option '$key'"; + $hexopt{$key} = "0x".$val; +} + sub add_config($) { my $arg=shift; - if ($arg =~ m/^([A-Z0-9_]+)/) { + if ($arg =~ m/^(\w+)/) { + # Have option default to 'on' $config{$1} = 1; + } else { + die "Do not understand config variable '$arg'"; } } -sub check_deps($) +######################################## +# Turn option off, iff it already exists +sub disable_config($) { + my $key = shift; + + $config{$key} = 0 if (exists $config{$key}); +} + +################################################################# +# Make a list of dependencies and the number of references for it +sub check_deps($$) +{ + my $key=shift; my $arg=shift; + + $depmods{$key}=$arg; $arg=$arg." "; while ($arg ne "") { @@ -28,32 +164,122 @@ sub check_deps($) } $arg =~ s/^[^ ]+ //; } + + return $ok; +} + +###################################################### +# Checks if all dependencies for the key are satisfied +sub deps_ok($) +{ + my $key=shift; + my $arg=$depmods{$key}; + my $ok=1; + + if ($arg eq "") { + return $ok; + } + + $arg=$arg." "; + + +# printf "$key: deps are '$arg'\n"; + + while ($arg ne "") { + if ($arg =~ m/^([A-Z0-9_]+) /) { + if ((! exists $kernopts {$1}) || ($kernopts {$1} eq 'n')) { + printf "$key: Required kernel opt '$1' is not present\n"; + $ok=0; + } + } + if ($arg =~ m/^\!([A-Z0-9_]+) /) { + if ($kernopts {$1} eq 'y') { + printf "$key: Driver is incompatible with '$1'\n"; + $ok=0; + } + } + $arg =~ s/^[^ ]+ //; + } + + return $ok; } sub open_kconfig($$) { my ($dir,$file)=@_; my $in = new FileHandle; - my $skip=0; + my $disabled=0; + my $key; #print "opening $file\n"; - open $in,"$file"; + open $in,"$file" or die "File not found: $file"; while (<$in>) { # if (m;^\s*source[\s\"]+drivers/media/(video|dvb)/Kconfig;) { # next; # } - if (m|^\s*source[\s\"]+([^\n\s\"]+)[\n\s\"]|) { + + # start of a new stanza, reset + if (m/^\w/) { + $disabled = 0; + $default_seen = 0; + $key = undef; + } + + if (m|^\s*source\s+"([^"]+)"\s*$| || + m|^\s*source\s+(\S+)\s*$|) { open_kconfig($dir,"$dir/$1"); next; } - if (m|^\s+depends on (.*)\n|) { - check_deps ($1); + if (m|^\s+depends on\s+(.*)\n|) { + check_deps ($key,$1); } - if (m|^\s+select (.*)\n|) { - check_deps ($1); + if (m|^\s+select\s+(.*)\n|) { + check_deps ($key,$1); + } + if (m|^\s+bool(ean)?\s|) { + add_bool($key); + } + if (m|^\s+tristate\s|) { + add_tristate($key); + } + if (m|^\s+int\s|) { + add_int($key); + } + if (m|^\s+hex\s|) { + add_hex($key); + } + # Get default for int options + if (m|^\s+default "(\d+)"| && exists $intopt{$key}) { + set_int_value($key, $1); + } + # Get default for hex options + if (m|^\s+default "(0x)?([[:xdigit:]]+)"| && exists $hexopt{$key}) { + set_hex_value($key, $2); + } + # Override default for disabled tri/bool options + if (m/^\s+default (y|n|m|"yes"|"no")\s+(if .*)?$/ && + exists $tristate{$key} && $disabled) { + $default_seen = 1; + $_ = "\tdefault n\n"; + } + # check for end of config definition for disabled drivers + # we need to make sure we've disabled it, and add a bit + # to the help text + if (m|^\s*(---)?help(---)?\s*$| && $disabled) { + if(exists $tristate{$key} && !$default_seen) { + print OUT "\tdefault n\n"; + } + print OUT <<"EOF"; + depends on VIDEO_KERNEL_VERSION + help + WARNING! This driver needs at least kernel $minver{$key}! It may not + compile or work correctly on your kernel, which is too old. + +EOF + next; } - if (m|^\s*config (.*)\n|) { - my $key=$1; + if (m|^\s*config (\w+)\s*$|) { + $key=$1; add_config ($1); my $min=$minver { $key }; @@ -65,27 +291,22 @@ sub open_kconfig($$) { } else { die "Minimum version for $key not found at versions.txt"; } - if ( ($version < $minversion) | - ($level < $minlevel) | + if ( ($version < $minversion) || + ($level < $minlevel) || ($sublevel < $minsublevel) ) { - $skip=1; - printf "$key requires version $minversion.$minlevel.$minsublevel\n"; - - print OUT "# $key disabled due to incorrect version\nconfig $key\n\ttristate\n\tdefault n\n\n"; - next; + $disabled=1; + disable_config ($key); + print "$key requires version $minversion.$minlevel.$minsublevel\n"; + print OUT "# $key disabled for insufficient kernel version\n"; } else { -# printf "OK: $key requires version $minversion.$minlevel.$minsublevel\n"; - $skip=0; +# print "OK: $key requires version $minversion.$minlevel.$minsublevel\n"; + $disabled=0; } } s/^main(menu\s\"[^\"]+)/\1 - DON'T CHANGE IT!/; - if (m/^[\w]/) { - $skip=0; - } - if (!$skip) { - print OUT $_; - } + + print OUT $_; } close $in; } @@ -95,7 +316,7 @@ sub parse_versions () my $in = new FileHandle; my $ver; - open $in,"versions.txt"; + open $in,"versions.txt" or die "File not found: versions.txt"; while (<$in>) { if (m/\[([\d.]*)\]/) { $ver=$1; @@ -110,9 +331,11 @@ sub parse_versions () close $in; } +process_config("linux/config.h"); + parse_versions; -open IN,".version"; +open IN,".version" or die "File not found: .version"; while (<IN>) { if (m/KERNELRELEASE\s*[:]*[=]+\s*(\d+)\.(\d+)\.(\d+)/) { $version=$1; @@ -124,24 +347,126 @@ close IN; printf "Preparing to compile for kernel version %d.%d.%d\n",$version,$level,$sublevel; -open OUT,">Kconfig"; -print OUT "mainmenu \"V4L/DVB menu\"\n"; +open OUT,">Kconfig" or die "Cannot write Kconfig file"; -print OUT "source Kconfig.kern\n"; -open_kconfig ("../linux","../linux/drivers/media/Kconfig"); +print OUT <<"EOF"; +mainmenu "V4L/DVB menu" +source Kconfig.kern +config VIDEO_KERNEL_VERSION + bool "Enable drivers not supported by this kernel" + default n + ---help--- + Normally drivers that require a kernel newer $version.$level.$sublevel, + the kernel you are compiling for now, will be disabled. + + Turning this switch on will let you enabled them, but be warned + they may not work properly or even compile. + + They may also work fine, and the only reason they are listed as + requiring a newer kernel is that no one has tested them with an + older one yet. + + If the driver works, please post a report at V4L mailing list: + video4linux-list\@redhat.com. + + Unless you know what you are doing, you should answer N. + +EOF +open_kconfig ("../linux","../linux/drivers/media/Kconfig"); close OUT; while ( my ($key, $value) = each(%config) ) { delete $depend{$key}; } -open OUT,">Kconfig.kern"; +open OUT,">Kconfig.kern" or die "Cannot write Kconfig.kern file"; print OUT "config MODULES\n\tboolean\n\tdefault y\n\n"; +add_config('MODULES'); +add_bool('MODULES'); while ( my ($key, $value) = each(%depend) ) { - print OUT "# $key with $value refs\nconfig $key\n\ttristate\n\tdefault m\n\n"; + if ($kernopts{$key}) { + print OUT "# $key with $value refs\nconfig $key\n\ttristate\n\tdefault ". + $kernopts{$key}."\n\n"; + } else { + print OUT "# $key with $value refs\nconfig $key\n\ttristate\n\tdefault n #not found\n\n"; + } } close OUT; +# These options should default to off +disable_config('DVB_AV7110_FIRMWARE'); +disable_config('DVB_CINERGYT2_TUNING'); + +# Hack for check sound/oss/aci.h header + +my $mirodep="$kernel/sound/oss/aci.h"; +if (!open IN, $mirodep) { + my $key="RADIO_MIROPCM20"; +print <<"EOF2"; +$key: $mirodep is missing. + +***WARNING:*** You do not have the full kernel sources installed. +This does not prevent you from building the v4l-dvb tree if you have the +kernel headers, but the full kernel source is required in order to use +make menuconfig / xconfig / qconfig. + +If you are experiencing problems building the v4l-dvb tree, please try +building against a vanilla kernel before reporting a bug. + +Vanilla kernels are available at http://kernel.org. +On most distros, this will compile a newly downloaded kernel: + +cp /boot/config-`uname -r` <your kernel dir>/.config +cd <your kernel dir> +make all modules_install install + +Please see your distro's web site for instructions to build a new kernel. + +EOF2 + $kernopts{$key}='n'; +} +close IN; + +# Recursively check for broken dependencies +my $i; +do { + $i=0; + while ( my ($key,$value) = each(%kernopts) ) { + if ($value ne 'n') { + if (!deps_ok($key)) { + $kernopts{$key}='n'; + } + $i=$i+1; + } + } +} until (!$disable); + +# Produce a .config file if it's forced or one doesn't already exist +if (($force_kconfig eq 1) || !open IN,".config") { + open OUT,">.config" or die "Cannot write .config file"; + while ( my ($key,$value) = each(%tristate) ) { + if (!$config{$key}) { + print OUT "# CONFIG_$key is not set\n"; + } elsif ($kernopts{$key}) { + if ($kernopts{$key} eq 'n') { + print OUT "# CONFIG_$key is not set\n"; + } else { + print OUT "CONFIG_$key=".$kernopts{$key}."\n"; + } + } elsif ($value eq 'tristate') { + print OUT "CONFIG_$key=m\n"; + } else { # must be 'bool' + print OUT "CONFIG_$key=y\n"; + } + } + while ( my ($key,$value) = each(%intopt) ) { + print OUT "CONFIG_$key=$value\n"; + } + while ( my ($key,$value) = each(%hexopt) ) { + print OUT "CONFIG_$key=$value\n"; + } + close OUT; +} |