diff options
Diffstat (limited to 'v4l')
-rw-r--r-- | v4l/Makefile | 83 | ||||
-rwxr-xr-x | v4l/scripts/make_kconfig.pl | 537 | ||||
-rwxr-xr-x | v4l/scripts/make_makefile.pl | 263 |
3 files changed, 488 insertions, 395 deletions
diff --git a/v4l/Makefile b/v4l/Makefile index bed3a0e42..963146eaa 100644 --- a/v4l/Makefile +++ b/v4l/Makefile @@ -31,17 +31,58 @@ endif # default compilation rule default:: config-compat.h Makefile.media links .version - echo srcdir $(SRCDIR) + @if [ "x$(SRCDIR)" != x ]; then echo SRCDIR is $(SRCDIR) ; fi $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) $(MYCFLAGS) modules ./scripts/rmmod.pl check ################################################# # Object specific rules +# Targets which don't need Makefile.media's rules +no-makefile-media-targets := %config clean distclean release snapshot snap \ + tarball release %links start insmod load stop rmmod unload reload \ + card% update push %commit help debug ivtv% cx88-ivtv lxdialog + +# Targets which don't need .myconfig to exist, to keep us from including it +no-dot-config-targets := $(no-makefile-media-targets) %install remove + +dot-config := 1 +ifneq ($(filter $(no-dot-config-targets), $(MAKECMDGOALS)),) + ifeq ($(filter-out $(no-dot-config-targets), $(MAKECMDGOALS)),) + dot-config := 0 + endif +endif + +makefile-media := 1 +ifneq ($(filter $(no-makefile-media-targets), $(MAKECMDGOALS)),) + ifeq ($(filter-out $(no-makefile-media-targets), $(MAKECMDGOALS)),) + makefile-media := 0 + endif +endif + +ifeq ($(dot-config),1) -include $(obj)/.myconfig +endif + +ifeq ($(makefile-media),1) -include $(obj)/Makefile.media -include $(obj)/Makefile.sound +endif + +-include $(obj)/.kconfig.dep -include $(obj)/Makefile.ivtv +# make will try to automatically rebuild the Makefile and all includes, +# and if any of them change, make will start over with the updated files + +.myconfig: .config Kconfig + ./scripts/make_myconfig.pl + +# If it doesn't exist, this rule will build Makefile.media. If it does +# exist, it will have dependency information in it, and only be rebuilt +# when necessary. +Makefile.media: + scripts/make_makefile.pl + ################################################# # CFLAGS configuration @@ -131,7 +172,7 @@ export LC_ALL ################################################# # all file compilation rule -all:: allmodconfig default +all:: default ################################################# # installation invocation rules @@ -143,7 +184,7 @@ remove rminstall:: media-rminstall ivtv-rminstall ################################################# # Compiling preparation rules -.version:: +.version: ifneq ($(KERNELRELEASE),) @echo -e VERSION=$(VERSION)\\nPATCHLEVEL:=$(PATCHLEVEL)\\nSUBLEVEL:=$(SUBLEVEL)\\nKERNELRELEASE:=$(KERNELRELEASE) > $(obj)/.version ifneq ($(SRCDIR),) @@ -154,9 +195,6 @@ else @uname -r|perl -ne 'if (/^([0-9]*)\.([0-9])*\.([0-9]*)(.*)$$/) { printf ("VERSION=%s\nPATCHLEVEL:=%s\nSUBLEVEL:=%s\nKERNELRELEASE:=%s.%s.%s%s\n",$$1,$$2,$$3,$$1,$$2,$$3,$$4); };' > $(obj)/.version endif -Makefile.media:: .version - scripts/make_makefile.pl $(KDIR) - release:: ifneq ($(VER),) @echo "Forcing compiling to version $(VER)." @@ -226,7 +264,8 @@ clean:: distclean:: clean -rm -f .version .*.o.flags .*.o.d Makefile.media \ - Kconfig Kconfig.kern .config .config.cmd .myconfig + Kconfig Kconfig.kern .config .config.cmd .myconfig \ + .kconfig.dep -rm -rf .tmp_versions -rm -f scripts/lxdialog scripts/kconfig @find .. -name '*.orig' -exec rm '{}' \; @@ -261,26 +300,36 @@ LXDIALOG_DIR := $(shell if [ -d $(KDIR)/scripts/kconfig/lxdialog ]; then echo kc LXDIALOG_LNK := $(if $(LXDIALOG_DIR),scripts/kconfig,scripts/lxdialog) LXDIALOG := $(KDIR)/scripts/$(LXDIALOG_DIR)lxdialog/lxdialog -.myconfig : .config - ./scripts/make_myconfig.pl +# Ideally, some kind of oldconfig process would be used to update .config +# without destroying the user's configuration. Lacking that, we will +# just touch .config if it already exists, and run make_kconfig if it +# doesn't. +.config: .version + @echo Updating/Creating .config + @if [ -e .config ]; then touch .config ; else \ + ./scripts/make_kconfig.pl $(KDIR) ; fi -xconfig:: links .version $(QCONF) +Kconfig: .version ./scripts/make_kconfig.pl $(KDIR) + +# With make -j, it's possible that both the .config and Kconfig rules +# will run at the same time, running make_kconfig.pl twice. There +# doesn't appear to be any way around this, but it doesn't cause a +# failure. One make_kconfig.pl will just overwrite the other's output. + +xconfig:: $(QCONF) Kconfig $(QCONF) Kconfig -gconfig:: links .version $(GCONF) - ./scripts/make_kconfig.pl $(KDIR) +gconfig:: $(GCONF) Kconfig $(QCONF) Kconfig -config:: links .version $(CONF) - ./scripts/make_kconfig.pl $(KDIR) +config:: $(CONF) Kconfig $(CONF) Kconfig -menuconfig:: links .version $(MCONF) lxdialog - ./scripts/make_kconfig.pl $(KDIR) +menuconfig:: $(MCONF) lxdialog Kconfig $(MCONF) Kconfig -allyesconfig allmodconfig:: links .version +allyesconfig allmodconfig:: .version ./scripts/make_kconfig.pl $(KDIR) 1 # rule to build kernel conf programs diff --git a/v4l/scripts/make_kconfig.pl b/v4l/scripts/make_kconfig.pl index 950e620d4..6f1b108c1 100755 --- a/v4l/scripts/make_kconfig.pl +++ b/v4l/scripts/make_kconfig.pl @@ -1,5 +1,6 @@ #!/usr/bin/perl use FileHandle; +use strict; my %depend = (); my %minver = (); @@ -9,63 +10,40 @@ my %hexopt = (); my %tristate = (); my %kernopts = (); my %depmods = (); -my $version, $level, $sublevel, $kernver; +my ($version, $level, $sublevel, $kernver); -my $kernel=shift; -my $force_kconfig=shift; +my $kernel = shift; +my $force_kconfig = shift; -#my $debug=1; - -#!/usr/bin/perl -use FileHandle; +my $debug=0; ########################################################### -# Checks config.h and autoconf.h for current kernel defines -sub process_config ($) +# Read a .config file (first argument) and put the resulting options in a +# hash, which is returned. This subroutine should be called in a hash +# context or it will not be very useful. +sub process_config($) { my $filename = shift; + my %conf; my $in = new FileHandle; - open $in,"$kernel/include/$filename" or die "File not found: $kernel/include/$filename"; + open $in, $filename or die "File not found: $filename"; while (<$in>) { - if (m/\#define\s+CONFIG_([^ ]*)_ON_SMP\s+(.*)\n/) { - my $key=$1; - my $value=$2; - printf "defined $key as $value\n" if $debug; - if ( $value == 1 ) { - $value='y'; - } - $kernopts{$key}=$value; + if (/^CONFIG_(\w+)\s*=\s*(\S.*?)\s*$/) { + my $c = \($conf{$1} = $2); + $$c =~ y/nmy/012/ if $$c =~ /^.$/; next; } - if (m/\#define\s+CONFIG_([^ ]*)_MODULE\s+(.*)\n/) { - my $key=$1; - my $value=$2; - printf "defined $key as $value\n" if $debug; - if ( $value == 1 ) { - $value='m'; - } - $kernopts{$key}=$value; + if (/^# CONFIG_(\w+) is not set$/) { + $conf{$1} = 0; next; } - if (m/\#define\s+CONFIG_([^ ]*)\s+(.*)\n/) { - my $key=$1; - my $value=$2; - printf "defined $key as $value\n" if $debug; - if ( $value == 1 ) { - $value='y'; - } - $kernopts{$key}=$value; - next; - } - if (m/\#undef\s+CONFIG_([^ ]*)\n/) { - printf "undefined $1\n" if $debug; - $kernopts{$1}='n'; - next; + unless (/^#|$/) { + print "Confused by this line in $filename:\n$_"; } } - close $in; + return %conf; } sub add_bool($) @@ -73,10 +51,8 @@ sub add_bool($) my $arg=shift; exists $config{$arg} or die "Adding unknown boolean '$arg'"; - $tristate{$arg}="bool"; - printf "Boolean:%s\n",$arg if $debug; - - $kernopts{$arg}='y'; + print "Boolean: $arg\n" if $debug; + $tristate{$arg} = "bool"; } sub add_tristate($) @@ -84,9 +60,10 @@ sub add_tristate($) my $arg=shift; exists $config{$arg} or die "Adding unknown tristate '$arg'"; + print "Tristate: $arg\n" if $debug; $tristate{$arg}="tristate"; - - $kernopts{$arg}='m'; + # tri default is 'm' + $config{$arg} = 1 if($config{$arg}); } sub add_int($) @@ -120,18 +97,17 @@ sub set_hex_value($$) my $val = shift; exists $hexopt{$key} or die "Default for unknown hex option '$key'"; - $hexopt{$key} = "0x".$val; + $hexopt{$key} = "0x$val"; } sub add_config($) { - my $arg=shift; + my $arg = shift; - if ($arg =~ m/^(\w+)/) { - # Have option default to 'on' - $config{$1} = 1; + if ($arg =~ /^(\w+)\s*$/) { + $config{$1} = 2; } else { - die "Do not understand config variable '$arg'"; + die "Do not understand config variable '$arg'"; } } @@ -144,79 +120,172 @@ sub disable_config($) $config{$key} = 0 if (exists $config{$key}); } -################################################################# -# Make a list of dependencies and the number of references for it -sub check_deps($$) +# %{$depend{'FOO'}} lists all variables which depend on FOO. This is the +# reverse of the variables that FOO depends on. +my %depend = (); +sub finddeps($$) { - my $key=shift; - my $arg=shift; - - if ($depmods{$key}) { - $depmods{$key}=$depmods{$key}." $arg"; - } else { - $depmods{$key}=$arg; - } - $arg=$arg." "; - - while ($arg ne "") { - if ($arg =~ m/^([A-Z0-9_]+) /) { - my $val=$1; - my $prev=$depend{$val}; - $depend { $val } = 1+$prev; - } - $arg =~ s/^[^ ]+[ ]+//; - } + my $key = shift; + my $deps = shift; - return $ok; + $deps =~ s/^\W+//; + $depend{$_}{$key} = 1 foreach(split(/\W[\Wynm]*/, $deps)); } -###################################################### -# Checks if all dependencies for the key are satisfied -sub deps_ok($) +# @{$depends{'FOO'}} is a list of dependency expressions that FOO depends +# on. This is the reverse of the variables that depend on FOO. +my %depends = (); +sub depends($$) { - my $key=shift; - my $arg=$depmods{$key}; - my $ok=1; + my $key = shift; + my $deps = shift; - if ($arg eq "") { - return $ok; + if(!defined $key || $key eq '') { + print "Got bad key with $deps\n"; + return; } + finddeps($key, $deps); + push @{$depends{$key}}, $deps; +} - $arg=$arg." "; - - - printf "$key: deps are '$arg'\n" if $debug; +sub selects($$$) +{ + my $key = shift; + my $select = shift; + my $if = shift; + + finddeps($key, $select); + if(defined $if) { + finddeps($key, $if); + # Transform "select X if Y" into "depends on !Y || X" + $select = "!($if) || ($select)"; + } + push @{$depends{$key}}, $select; +} - 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; +# Needs: +# %depend <- %depend{FOO} lists the variables that depend on FOO +# %depends <- %depends{FOO} lists the dependency expressions for FOO +# %config <- the value of all media variables +# %kernopts <- the value of all kernel variables (including media ones) +# +# Checks the dependencies of all media variables, recursively. Returns +# a new hash that has the new values of all media variables. +sub checkdeps() +{ + my %allconfig; + + @allconfig{keys %depend} = @kernopts{keys %depend}; + @allconfig{keys %config} = values %config; + # Set undef values to 0 + map { defined $_ or $_ = 0 } values %allconfig; + + # First run, check deps for all the v4l-dvb variables. Following + # runs, check all variables which depend on a variable that was + # changed. Stop when no more variables change. + for(my %changed = (), my @tocheck = keys %config; @tocheck; + @tocheck = keys %changed, %changed = ()) { + foreach (@tocheck) { + next unless($allconfig{$_}); # skip disabled vars + if (!checkvardeps($_)) { + $changed{$_} = 1 foreach keys %{$depend{$_}}; } } - if ($arg =~ m/^\!([A-Z0-9_]+) /) { - if ($kernopts {$1} eq 'y') { - printf "$key: Driver is incompatible with '$1'\n"; - $ok=0; + } + return map { $_ => $allconfig{$_} } keys %config; + + # Check the dependencies of a variable, if one fails the variable + # is set to 0. Returns 0 if the variable failed, 1 if it passed. + sub checkvardeps($) { + my $key = shift; + my $deps = $depends{$key}; + foreach (@$deps) { + if (!eval(toperl($_))) { + $allconfig{$key} = 0; + return 0; } } - $arg =~ s/^[^ ]+ //; + return 1; } - return $ok; + # Convert a Kconfig expression to a Perl expression + sub toperl($) + { + $_ = shift; + + # Turn n,m,y into 0,1,2 + s/\bn\b/0/g; s/\bm\b/1/g; s/\by\b/2/g; + + # Turn = into ==, but keep != as != (ie. not !==) + s/(?<!!)=/==/g; + + # Turn FOO into the value of $allconfig{FOO} + s/\b([A-Za-z_]\w*)\b/$allconfig{$1}/g; + + return $_; + } } +# Text to be added to disabled options +my $disabled_msg = <<'EOF'; + ---help--- + WARNING! This driver needs at least kernel %s! It may not + compile or work correctly on your kernel, which is too old. + +EOF + +# List of all kconfig files read in, used to make dependencies for the +# output combined Kconfig file. +my @kconfigfiles = (); + +# Read and parse a Kconfig file. First argument is base of source +# directory tree, the second is the file to open (with path). Recursivly +# parses Kconfig files from 'source' directives. +# +# Prints to OUT a combined version of all the Kconfig files. This file +# is edited slightly to disable options that need a newer kernel. sub open_kconfig($$) { my ($dir,$file)=@_; my $in = new FileHandle; - my $disabled=0; my $key; + my $disabled = 0; + my $in_help = 0; + my $default_seen = 0; -print "opening $file\n" if $debug; - open $in,"$file" or die "File not found: $file"; + print "Opening $file\n" if $debug; + open $in, '<', $file or die "File not found: $file"; + push @kconfigfiles, $file; while (<$in>) { + # In our Kconfig files, the first non-help line after the + # help text always has no indention. Technically, the + # help text is ended by just by the indention decreasing, + # but that is a pain to keep track of. + if ($in_help && /^\S/) { + $in_help = 0; + } elsif ($in_help) { + # Still inside help text + next; + } + + # Start of help text + if (/^\s*(---)?help(---)?\s*$/) { + $in_help = 1; + # Insert VIDEO_KERNEL_VERSION dependency, default + # n line, and help text note for disabled drivers. + if ($disabled) { + if(exists $tristate{$key} && !$default_seen) { + print OUT "\tdefault n\n"; + } + print OUT "\tdepends on VIDEO_KERNEL_VERSION\n"; + $_ = sprintf($disabled_msg, $minver{$key}); + } + next; + } + # No help text should get processed past this point + $in_help and die "I'm very confused"; + # start of a new stanza, reset - if (m/^\w/) { + if (/^\w/) { $disabled = 0; $default_seen = 0; $key = undef; @@ -224,89 +293,71 @@ print "opening $file\n" if $debug; if (m|^\s*source\s+"([^"]+)"\s*$| || m|^\s*source\s+(\S+)\s*$|) { - open_kconfig($dir,"$dir/$1"); + open_kconfig($dir, "$dir/$1"); + $_ = ''; # don't print the source line itself next; } - if (m|^\s+depends on\s+(.+?)\s*$|) { - check_deps ($key,$1); - } - # If a "select" dependency is not satisfied, that - # dependency is broken - if (m|^\s+select\s+(.+?)\s*(if .*?)?\s*$|) { - 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); + + if (m|^\s*config (\w+)\s*$|) { + $key = $1; + add_config($key); + + if (exists $minver{$key} && + cmp_ver($minver{$key}, $kernver) > 0) { + $disabled = 1; + disable_config($key); + print "$key: Requires at least kernel $minver{$key}\n"; + print OUT "# $key disabled for insufficient kernel version\n"; + } else { + $disabled=0; + } + } elsif (m|^\s*comment\s+"[^"]*"\s*$|) { + $key = 'comment'; + } elsif (m|^\s*menu\s+"[^"]*"\s*$|) { + $key = 'menu'; } + + # Don't process any directives in comment blocks (or menus) + next if ($key eq 'comment' || $key eq 'menu'); + + add_bool($key) if(/^\s*bool(ean)?\s/); + add_tristate($key) if (/^\s*tristate\s/); + add_int($key) if (/^\s*int\s/); + add_hex($key) if (/^\s*hex\s/); + + depends($key, $1) if (m|^\s*depends on\s+(.+?)\s*$|); + selects($key, $1, $3) if (m|^\s*select\s+(\w+)(\s+if\s+(.+?))?\s*$|); + # Get default for int options - if (m|^\s+default "(\d+)"| && exists $intopt{$key}) { + if (m|^\s*default "(\d+)"| && exists $intopt{$key}) { set_int_value($key, $1); + next; } # Get default for hex options - if (m|^\s+default "(0x)?([[:xdigit:]]+)"| && exists $hexopt{$key}) { + if (m|^\s*default "(0x)?([[:xdigit:]]+)"| && exists $hexopt{$key}) { set_hex_value($key, $2); + next; } # Override default for disabled tri/bool options - if (m/^\s+default (y|n|m|"yes"|"no")\s+(if .*)?$/ && + # We don't care about the default for tri/bool options otherwise + if (m/^\s*default (y|n|m|"yes"|"no")(\s+if .*)?\s*$/ && 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 (\w+)\s*$|) { - $key=$1; - add_config ($1); - - if (exists $minver{$key} && - cmp_ver($minver{$key}, $kernver) > 0) { - $disabled=1; - disable_config ($key); - print "$key requires version $minver{$key}\n"; - print OUT "# $key disabled for insufficient kernel version\n"; - } else { - printf "OK: $key requires version %s\n", exists $minver{$key}?$minver{$key}:"any" if $debug; - $disabled=0; - } - } - - s/^main(menu\s\"[^\"]+)/\1 - DON'T CHANGE IT!/; - + } continue { print OUT $_; } close $in; } -sub parse_versions () +sub parse_versions() { my $in = new FileHandle; my $ver; - open $in,"versions.txt" or die "File not found: versions.txt"; + open $in, '<versions.txt' or die "File not found: versions.txt"; while (<$in>) { if (/\[(\d+\.\d+\.\d+)\]/) { $ver = $1; @@ -318,6 +369,21 @@ sub parse_versions () close $in; } +# Read in the .version file to get the kernel version +sub get_version() +{ + open IN, '<.version' or die 'File not found: .version'; + while (<IN>) { + if (/KERNELRELEASE\s*[:]*[=]+\s*(\d+)\.(\d+)\.(\d+)/) { + $version=$1; + $level=$2; + $sublevel=$3; + return $kernver="$version.$level.$sublevel"; + } + } + close IN; +} + # Like ver1 <=> ver2, but understands X.Y.Z version strings sub cmp_ver($$) { @@ -333,28 +399,38 @@ sub cmp_ver($$) return $v1_sublevel <=> $v2_sublevel; } -process_config("linux/autoconf.h"); +# Get Kernel's config settings +%kernopts = process_config("$kernel/.config"); -parse_versions; +# Modules must be on, or building out of tree drivers makes no sense +if(!$kernopts{MODULES}) { + print <<"EOF"; +You appear to have loadable modules turned off in your kernel. You can +not compile the v4l-dvb drivers, as modules, and use them with a kernel +that has modules disabled. -open IN,".version" or die "File not found: .version"; -while (<IN>) { - if (m/KERNELRELEASE\s*[:]*[=]+\s*(\d+)\.(\d+)\.(\d+)/) { - $version=$1; - $level=$2; - $sublevel=$3; - $kernver="$version.$level.$sublevel"; - } +If you want to compile these drivers into your kernel, you should +use 'make kernel-links' to link the source for these drivers into +your kernel tree. Then configure and compile the kernel. +EOF + exit -1; } -close IN; + +# Get minimum kernel version for our variables +parse_versions(); + +# Get kernel version +get_version(); print "Preparing to compile for kernel version $kernver\n"; -open OUT,">Kconfig" or die "Cannot write Kconfig file"; +kernelcheck(); +open OUT, ">Kconfig" or die "Cannot write Kconfig file"; print OUT <<"EOF"; mainmenu "V4L/DVB menu" source Kconfig.kern +source Kconfig.sound config VIDEO_KERNEL_VERSION bool "Enable drivers not supported by this kernel" default n @@ -376,38 +452,67 @@ config VIDEO_KERNEL_VERSION EOF -open_kconfig ("../linux","../linux/drivers/media/Kconfig"); -open_kconfig (".","./Kconfig.sound"); - -print OUT "source Kconfig.sound\n"; +open_kconfig('../linux', '../linux/drivers/media/Kconfig'); +open_kconfig('.', './Kconfig.sound'); close OUT; -while ( my ($key, $value) = each(%config) ) { - delete $depend{$key}; -} +# These options should default to off +disable_config('DVB_AV7110_FIRMWARE'); +disable_config('DVB_CINERGYT2_TUNING'); +disable_config('DVB_FE_CUSTOMISE'); -open OUT,">Kconfig.kern" or die "Cannot write Kconfig.kern file"; +# Check dependencies +my %newconfig = checkdeps(); -while ( my ($key, $value) = each(%depend) ) { - 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"; - } +# TODO: tell the user which options were disabled at this point +%config = %newconfig; + +# Create Kconfig.kern, listing all non-media (i.e. kernel) variables +# that something depended on. +$depend{MODULES}{always} = 1; # Make sure MODULES will appear +open OUT, '>Kconfig.kern' or die "Cannot write Kconfig.kern file: $!"; +while (my ($key, $deps) = each %depend) { + next if exists $config{$key}; # Skip media variables + + print OUT "# Needed by ", join(', ', keys %$deps), "\n"; + print OUT "config $key\n\ttristate\n"; + print OUT "\tdefault ", qw(n m y)[$kernopts{$key}], "\n\n"; } close OUT; -# These options should default to off -disable_config('DVB_AV7110_FIRMWARE'); -disable_config('DVB_CINERGYT2_TUNING'); -disable_config('DVB_FE_CUSTOMISE'); +# Create make dependency rules for the Kconfig file +open OUT, '>.kconfig.dep' or die "Cannot write .kconfig.dep file: $!"; +print OUT 'Kconfig: '; +print OUT join(" \\\n\t", @kconfigfiles), "\n"; +close OUT; + +# Produce a .config file if forced or one doesn't already exist +if ($force_kconfig==1 || !-e '.config') { + open OUT, '>.config' or die "Cannot write .config file: $!"; + foreach (keys %tristate) { + if ($config{$_}) { + print OUT "CONFIG_$_=", qw(n m y)[$config{$_}], "\n"; + } else { + print OUT "# CONFIG_$_ is not set\n"; + } + } + while (my ($key,$value) = each %intopt) { + print OUT "CONFIG_$key=$value\n" if($config{$key}); + } + while (my ($key,$value) = each %hexopt) { + print OUT "CONFIG_$key=$value\n" if($config{$key}); + } + close OUT; + print "Created default (all yes) .config file\n"; +} -# Hack for check sound/oss/aci.h header +# Check for full kernel sources and print a warning +sub kernelcheck() +{ + my $fullkernel="$kernel/fs/fcntl.c"; + if (! -e $fullkernel) { + print <<"EOF2"; -my $fullkernel="$kernel/fs/fcntl.c"; -if (! -e $fullkernel) { - print <<"EOF2"; ***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 may be required in order to use @@ -426,45 +531,5 @@ make all modules_install install Please see your distro's web site for instructions to build a new kernel. EOF2 -} - -# 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; } diff --git a/v4l/scripts/make_makefile.pl b/v4l/scripts/make_makefile.pl index e0a099e9b..e1e08b578 100755 --- a/v4l/scripts/make_makefile.pl +++ b/v4l/scripts/make_makefile.pl @@ -1,186 +1,165 @@ #!/usr/bin/perl use FileHandle; -my $kernel=shift; -my $instdir = (); - +my %instdir = (); + +# Take a Makefile line of the form: +# obj-XXXXX = some_directory/ some_module.o +# +# All directories are processed by including the referenced Makefile and +# removing the directory. The modules are added to the list of modules +# to install. Prints the edited line to OUT. +# Arguments: directory Makefile is in, the objects, original line(s) from +# Makefile (with newlines intact). sub check_line($$$) { - my $dir=shift; - my $obj=shift; - my $arg=shift; - my $arg2=""; - - my $idir = $dir; - - $idir =~ s|^../linux/drivers/media/||; - - $arg=$arg." "; - - while ($arg ne "") { - if ($arg =~ m|^([^ /]+)/ |) { - my $newdir=$1; -# print "include $dir/$newdir/Makefile\n"; - open_makefile("$dir/$newdir/Makefile"); - $arg =~ s/^[^ ]+ //; - } else { - $arg =~ s/^([^ ]+ )//; - my $cur=$1; - $arg2 = $arg2.$cur; - - $cur =~ s/\s+$//; - $cur =~ s/\\$//; - $cur =~ s/\s+$//; - $cur =~ s/\.o$/.ko/; - - if ( ($cur ne "") && (! ($instdir { $idir } =~ m/($cur) /))) { - $instdir { $idir } = $instdir { $idir }.$cur." "; - } + my $dir = shift; + my $objs = shift; + my $orig = shift; + my $count = 0; + + foreach(split /\s+/, $objs) { + if (m|/$|) { # Ends in /, means it's a directory + # Delete this directory from original Makefile line + $orig =~ s/$_[ \t]*//; + $_ .= 'Makefile'; + # print STDERR "open new makefile $dir/$_\n"; + open_makefile("$dir/$_"); + next; } + + # It's a file, add it to list of files to install + s/\.o$/.ko/; + my $idir = $dir; + $idir =~ s|^../linux/drivers/media/||; + $instdir{$idir}{$_} = 1; + $count++; } - $arg2 =~ s/\s+$//; - if ($arg2 ne "") { -# print "arg=$arg2\n"; - print OUT "$obj$arg2\n"; - } + # Removing any tailling whitespace, just to be neat + $orig =~ s/[ \t]+$//mg; + + # Print out original line, less directories, if there is anything + # still there + print OUT $orig if($count); } +# Uses the string being assigned from a line of the form: +# EXTRA_CFLAGS += -Idrivers/media/something -Dwhatever +# +# All the -Idrivers/media/something options get deleted. All the source +# files are linked into the v4l directory and built from there, so and -I +# option for them is unnecessary. The line is printed to OUT if there is +# anything left after that. sub remove_includes($$) { - my $obj=shift; - my $arg=shift; - my $arg2=""; - - $arg=$arg." "; - - while ($arg ne "") { - if (!$arg =~ m|^(-I\s*[^ ]+) |) { - $arg2 = $arg2.$1; - $arg =~ s|^[^ ] ||; - } else { - $arg =~ s|^(-I\s*[^ ]+) ||; + my $flags = shift; + my $orig = shift; + my $count = 0; + + foreach(split /\s+/, $flags) { + if (m|^-Idrivers/media|) { + # Remove any -I flags from original Makefile line + $orig =~ s/$_[ \t]*//; + next; } + $count++; # Something wasn't deleted } - if ($arg2 ne "") { - print OUT "$obj$arg2\n"; - } + $orig =~ s/[ \t]+$//mg; + + # Print out original line if there is anything we didn't delete + print OUT $orig if($count); } sub open_makefile($) { - my $file= shift; + my $file = shift; my $in = new FileHandle; - my $dir= ""; - my $count=0; + my $orig; + + # only open a given Makefile once + return if exists $makefiles{$file}; + $makefiles{$file} = 1; - $file=~ m|^(.*)/[^/]*$|; - $dir=$1; + $file =~ m|^(.*)/[^/]*$|; + my $dir = $1; -#print "opening $file (dir=$dir)\n"; - open $in,"$file"; + # print STDERR "opening $file (dir=$dir)\n"; + $file =~ m|.*/(linux/.*)$|; + print OUT "# Including $1\n"; + open $in, $file; while (<$in>) { - if (m|\s*#|) { + # print STDERR "Line: $_"; + # Skip comment lines + if (/^\s*#/) { print OUT $_; next; } - if (m|^\s*include|) { - next; + m/^\s*-?include/ and die "Can't handle includes! In $file"; + + # Handle line continuations + if (/\\\n$/) { + $_ .= <$in>; + redo; } - if (count==1 || m|(^\s*EXTRA_CFLAGS.*=\s*)(.*/.*)\n|) { - remove_includes($1,$2); - if (m|[\\]\n|) { - $count=1; - } else { - $count=0; - } + + # $orig is what we will print, $_ is what we will parse + $orig = $_; + # Eat line continuations in string we will parse + s/\s*\\\n\s*/ /g; + # Eat comments + s/#.*$//; + + if (/^\s*obj-.*:?=\s*(\S.*?)\s*$/) { + # print STDERR "obj matched '$1'\n"; + check_line($dir, $1, $orig); # will print line for us next; } -# if (m|(^\s*obj.*=\s*)(.*/.*)\n|) { - if (count==2 || m|(^\s*obj.*=\s*)(.*)\n|) { - check_line($dir,$1,$2); - if (m|\\\n|) { - $count=1; - } else { - $count=0; - } + if (/^\s*EXTRA_CFLAGS\s+\+?=\s*(\S.*?)\s*$/) { + # print STDERR "cflags matched '$1'\n"; + remove_includes($1, $orig); # will print line for us next; } - print OUT $_; + print OUT $orig; } close $in; } -open OUT,">Makefile.media.new"; -open_makefile ("../linux/drivers/media/Makefile"); +open OUT, '>Makefile.media' or die 'Unable to write Makefile.media'; +open_makefile('../linux/drivers/media/Makefile'); # Creating Install rule -printf OUT "media-install::\n"; -printf OUT "\t\@echo \"Stripping debug info from files:\"\n"; -printf OUT "\t\@strip --strip-debug \$(inst-m)\n\n"; - -while ( my ($key, $value) = each(%instdir) ) { - printf OUT "\t\@echo -e \"\\nInstalling \$(KDIR26)/$key files:\"\n"; - printf OUT "\t\@install -d \$(KDIR26)/$key\n"; - - printf OUT "\t\@files='$value'; "; - printf OUT "for i in \$\$files;do if [ -e \$\$i ]; then echo -n \"\$\$i \";"; - printf OUT " install -m 644 -c \$\$i \$(KDIR26)/$key; fi; done; echo;\n\n"; +print OUT "media-install::\n"; +print OUT "\t\@echo \"Stripping debug info from files:\"\n"; +print OUT "\t\@strip --strip-debug \$(inst-m)\n\n"; + +while (my ($dir, $files) = each %instdir) { + print OUT "\t\@echo -e \"\\nInstalling \$(KDIR26)/$dir files:\"\n"; + print OUT "\t\@install -d \$(KDIR26)/$dir\n"; + print OUT "\t\@for i in ", join(' ', keys %$files), ";do "; + print OUT "if [ -e \"\$\$i\" ]; then echo -n \"\$\$i \";"; + print OUT " install -m 644 -c \$\$i \$(KDIR26)/$dir; fi; done; echo;\n\n"; } -printf OUT "\t/sbin/depmod -a \${KERNELRELEASE}\n\n"; +print OUT "\t/sbin/depmod -a \${KERNELRELEASE}\n\n"; # Creating Remove rule -printf OUT "media-rminstall::\n"; -printf OUT "\t\@echo -e \"\\nRemoving old \$(DEST) files\\n\"\n"; +print OUT "media-rminstall::\n"; +print OUT "\t\@echo -e \"\\nRemoving old \$(DEST) files\\n\"\n"; -while ( my ($key, $value) = each(%instdir) ) { - printf OUT "\t\@echo -e \"\\nRemoving old \$(KDIR26)/$key files:\"\n"; - printf OUT "\t\@files='$value'; "; +while ( my ($dir, $files) = each(%instdir) ) { + print OUT "\t\@echo -e \"\\nRemoving old \$(KDIR26)/$dir files:\"\n"; + print OUT "\t\@files='", join(' ', keys %$files), "'; "; - printf OUT "for i in \$\$files;do if [ -e \$(KDIR26)/$key/\$\$i ]; then "; - printf OUT "echo -n \"\$\$i \";"; - printf OUT " rm \$(KDIR26)/$key/\$\$i; fi; done; "; + print OUT "for i in \$\$files;do if [ -e \$(KDIR26)/$dir/\$\$i ]; then "; + print OUT "echo -n \"\$\$i \";"; + print OUT " rm \$(KDIR26)/$dir/\$\$i; fi; done; "; - printf OUT "for i in \$\$files;do if [ -e \$(KDIR26)/$key/\$\$i.gz ]; then "; - printf OUT "echo -n \"\$\$i.gz \";"; - printf OUT " rm \$(KDIR26)/$key/\$\$i.gz; fi; done; echo;\n\n"; + print OUT "for i in \$\$files;do if [ -e \$(KDIR26)/$dir/\$\$i.gz ]; then "; + print OUT "echo -n \"\$\$i.gz \";"; + print OUT " rm \$(KDIR26)/$dir/\$\$i.gz; fi; done; echo;\n\n"; } +# Print dependencies of Makefile.media +print OUT "Makefile.media: ../linux/drivers/media/Makefile \\\n"; +print OUT join(" \\\n", map("\t../linux/drivers/media/$_/Makefile", keys %instdir)); +print OUT "\n"; close OUT; - -while ( my ($key, $value) = each(%config) ) { - delete $depend{$key}; -} - -open OUT,">Kconfig.kern"; -while ( my ($key, $value) = each(%depend) ) { - print OUT "# $key with $value refs\nconfig $key\n\ttristate\n\tdefault m\n\n"; -} -close OUT; - -if (open IN,"Makefile.media") { - close IN; - my $changed=0; - if (open IN,"diff Makefile.media Makefile.media.new|") { - while (<IN>) { - if ($_ ne "") { - $changed=1; - } - } - close IN; - if ($changed) { - printf("One or more linux Makefiles had changed. Makefile.media rewrited.\n"); - system ("mv Makefile.media.new Makefile.media"); - } else { - system ("rm Makefile.media.new"); - } - } -} else { - printf("Creating Makefile.media.\n"); - system "mv Makefile.media.new Makefile.media"; -} - -if (open IN,".myconfig") { - close IN; -} else { - system "./scripts/make_kconfig.pl $kernel 1"; -} |