summaryrefslogtreecommitdiff
path: root/v4l/scripts
diff options
context:
space:
mode:
Diffstat (limited to 'v4l/scripts')
-rwxr-xr-xv4l/scripts/analyze_build.pl179
1 files changed, 179 insertions, 0 deletions
diff --git a/v4l/scripts/analyze_build.pl b/v4l/scripts/analyze_build.pl
new file mode 100755
index 000000000..945377fa4
--- /dev/null
+++ b/v4l/scripts/analyze_build.pl
@@ -0,0 +1,179 @@
+#!/usr/bin/perl
+
+# Copyright (C) 2006 Trent Piepho <xyzzy@speakeasy.org>
+# Scans a tree of Linux Kernel style Makefiles, and builds lists of what
+# builds what.
+# Outputs three lists:
+# 1. Kconfig variables associated with the kernel module(s) they turn on
+# 2. Kernel modules associated with their source file(s)
+# 3. Kconfig variables associated with all the source file(s) they turn on
+#
+# Optional options:
+# Prefix relative to source tree root to start scanning in. This
+# will be stripped from the beginnings of all filenames printed out.
+# Default is 'linux/drivers/media'
+# Root of source tree
+# Default is to use 'hg root' command and if that fails the cwd
+#
+# Most usefull with grep, for example
+# List of modules and source files used by DVB_BUDGET_AV
+# deps.pl | grep DVB_BUDGET_AV
+#
+# Kconfig variable and kernel module that use dvb-usb-init.c
+# deps.pl | grep dvb-usb-init.c
+#
+# Kconfig variable and source files that make dvb-core.ko
+# deps.pl | grep dvb-core.ko
+#
+# Also has some ability to check Makefiles for errors
+use strict;
+use FileHandle;
+
+# Print out some extra checks of Makefile correctness
+my $check = 0;
+
+# Directory to start in. Will be stripped from all filenames printed out.
+my $prefix = 'linux/drivers/media/';
+
+# Root of source tree
+my $root;
+
+# List of Makefile's opened
+my %makefiles = ();
+
+# For each Kconfig variable, a list of modules it builds
+my %config = ();
+
+# For each module that is made up of multiple source files, list of sources
+my %multi = ();
+
+sub open_makefile($) {
+ my $file = shift;
+
+ # only open a given Makefile once
+ return if exists $makefiles{$file};
+ $makefiles{$file} = 1;
+
+ $file =~ m|^(.*)/[^/]*$|;
+ my $dir = $1;
+
+# print STDERR "opening $root$file (dir=$dir)\n";
+ my $in = new FileHandle;
+ open $in, '<', "$root$file" or die "Unable to open Makefile '$root$file': $!";
+
+ while (<$in>) {
+ # print STDERR "Line: $_";
+ # Skip comment and blank lines
+ next if (/^\s*(#.*)?$/);
+ m/^\s*\-?include/ and die "Can't handle includes! In $file";
+
+ # Handle line continuations
+ if (/\\\n$/) {
+ $_ .= <$in>;
+ redo;
+ }
+ # Eat line continuations in string we will parse
+ s/\s*\\\n\s*/ /g;
+ # Eat comments
+ s/#.*$//;
+
+ if (/^\s*obj-(\S+)\s*([:+]?)=\s*(\S.*?)\s*$/) {
+ print STDERR "Should use '+=' in $file:$.\n$_\n" if ($check && $2 ne '+');
+ my ($var,$targets) = ($1, $3);
+ if ($var =~ /\$\(CONFIG_(\S+)\)$/) {
+ $var = $1;
+ } elsif ($var !~ /^[ym]$/) {
+ print STDERR "Confused by obj assignment '$var' in $file:$.\n$_";
+ }
+ foreach(split(/\s+/, $targets)) {
+ if (m|/$|) { # Ends in /, means it's a directory
+ open_makefile("$dir/$_".'Makefile');
+ } elsif (/^(\S+)\.o$/) {
+ push @{$config{$var}}, "$dir/$1";
+ } else {
+ print STDERR "Confused by target '$_' in $file:$.\n";
+ }
+ }
+ next;
+ }
+ if (/(\S+)-objs\s*([:+]?)=\s*(\S.*?)\s*$/) {
+ print STDERR "Should use ':=' in $file:$.\n$_\n" if ($check && $2 ne ':');
+ my @files = split(/\s+/, $3);
+ map { s|^(.*)\.o$|$dir/\1| } @files;
+ $multi{"$dir/$1"} = \@files;
+ next;
+ }
+ if (/^\s*EXTRA_CFLAGS\s*([:+]?)=\s*(\S.*?)\s*$/) {
+ if ($check) {
+ sub allI { /^-I/ or return 0 foreach split(/\s+/, $_[0]);return 1; }
+ my $use = allI($2) ? ':' : '+';
+ print STDERR "Should use '$use=' with EXTRA_CFLAGS in $file:$.\n$_\n"
+ if ($1 ne $use);
+ }
+ next;
+ }
+ print STDERR "Odd line $file:$.\n$_\n" if ($check);
+ }
+}
+
+if ($#ARGV >= 0) {
+ $prefix = $ARGV[0];
+ $prefix .= '/' unless ($prefix =~ m|/$|);
+}
+
+# Find root of source tree: command line, then Hg command, lastly cwd
+if ($#ARGV >= 1) {
+ $root = $ARGV[1];
+ $root .= '/' unless ($root =~ m|/$|);
+} else {
+ $root = `hg root 2>/dev/null`;
+ if($? == 0) {
+ chomp $root;
+ $root .= '/';
+ } else {
+ $root = '';
+ }
+}
+print "# Using source tree root '$root'\n" if ($root ne '');
+
+open_makefile($prefix."Makefile");
+
+print "# Kconfig variable = kernel modules built\n";
+foreach my $var (keys %config) {
+ my @list = @{$config{$var}};
+ map { s/^$prefix(.*)$/\1.ko/ } @list;
+ printf "%-22s= %s\n", $var, join(' ', @list);
+}
+
+print "\n# kernel module = source files\n";
+my %modules = ();
+foreach my $mods (values %config) {
+ $modules{$_} = 1 foreach @$mods;
+}
+foreach (keys %modules) {
+ /$prefix(.*)$/;
+ printf "%-30s = ", "$1.ko";
+ if (exists $multi{$_}) {
+ my @list = @{$multi{$_}};
+ map { s/^$prefix(.*)$/\1.c/ } @list;
+ print join(' ', @list), "\n";
+ } else {
+ print "$1.c\n";
+ }
+}
+
+print "\n# Kconfig varible = source files\n";
+while (my ($var, $list) = each %config) {
+ my @outlist = ();
+ foreach (@$list) {
+ if (exists $multi{$_}) {
+ push @outlist, @{$multi{$_}};
+ } else {
+ push @outlist, $_;
+ }
+ }
+ map { s/^$prefix(.*)$/\1.c/ } @outlist;
+ printf "%-22s= %s\n", $var, join(' ', @outlist);
+}
+
+exit;