summaryrefslogtreecommitdiff
path: root/v4l/scripts/make_kconfig.pl
diff options
context:
space:
mode:
Diffstat (limited to 'v4l/scripts/make_kconfig.pl')
-rwxr-xr-xv4l/scripts/make_kconfig.pl393
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;
+}