*: reuse more strings
[oweals/busybox.git] / examples / depmod.pl
index f6d4df85c39f4629e0bc87fe39bd9091eb30ecd4..809dc08b39e85de8b384ccaeddc237262162ac27 100755 (executable)
@@ -1,5 +1,5 @@
 #!/usr/bin/perl -w
 #!/usr/bin/perl -w
-# vi: set ts=4:
+# vi: set sw=4 ts=4:
 # Copyright (c) 2001 David Schleef <ds@schleef.org>
 # Copyright (c) 2001 Erik Andersen <andersen@codepoet.org>
 # Copyright (c) 2001 Stuart Hughes <seh@zee2.com>
 # Copyright (c) 2001 David Schleef <ds@schleef.org>
 # Copyright (c) 2001 Erik Andersen <andersen@codepoet.org>
 # Copyright (c) 2001 Stuart Hughes <seh@zee2.com>
@@ -13,7 +13,7 @@
 
 # This program is free software; you can redistribute it and/or modify it
 # under the same terms as Perl itself.
 
 # This program is free software; you can redistribute it and/or modify it
 # under the same terms as Perl itself.
-use Getopt::Long;
+use Getopt::Long qw(:config no_auto_abbrev no_ignore_case);
 use File::Find;
 use strict;
 
 use File::Find;
 use strict;
 
@@ -22,6 +22,10 @@ my $kdir="";
 my $basedir="";
 my $kernel="";
 my $kernelsyms="";
 my $basedir="";
 my $kernel="";
 my $kernelsyms="";
+my $symprefix="";
+my $all=0;
+my $quick=0;
+my $errsyms=0;
 my $stdout=0;
 my $verbose=0;
 my $help=0;
 my $stdout=0;
 my $verbose=0;
 my $help=0;
@@ -34,32 +38,45 @@ my $dep = {};
 my $mod = {};
 
 my $usage = <<TXT;
 my $mod = {};
 
 my $usage = <<TXT;
-$0 -b basedir { -k <vmlinux> | -F <System.map> } [options]... 
+$0 -b basedir { -k <vmlinux> | -F <System.map> } [options]...
   Where:
   Where:
-   -h --help         : Show this help screen
-   -b --basedir      : Modules base directory (e.g /lib/modules/<2.x.y>)
-   -k --kernel       : Kernel binary for the target (e.g. vmlinux)
-   -F --kernelsyms   : Kernel symbol file (e.g. System.map)
-   -n --stdout       : Write to stdout instead of <basedir>/modules.dep
-   -v --verbose      : Print out lots of debugging stuff
+   -h --help          : Show this help screen
+   -b --basedir       : Modules base directory (e.g /lib/modules/<2.x.y>)
+   -k --kernel        : Kernel binary for the target (e.g. vmlinux)
+   -F --kernelsyms    : Kernel symbol file (e.g. System.map)
+   -n --stdout        : Write to stdout instead of <basedir>/modules.dep
+   -v --verbose       : Print out lots of debugging stuff
+   -P --symbol-prefix : Symbol prefix
+   -a --all           : Probe all modules (default/only thing supported)
+   -e --errsyms       : Report any symbols not supplied by modules/kernel
 TXT
 
 # get command-line options
 GetOptions(
 TXT
 
 # get command-line options
 GetOptions(
-       "help|h"         => \$help,
-       "basedir|b=s"    => \$basedir,
-       "kernel|k=s"     => \$kernel,
-       "kernelsyms|F=s" => \$kernelsyms,
-       "stdout|n"       => \$stdout,
-       "verbose|v"      => \$verbose,
+       "help|h"            => \$help,
+       "basedir|b=s"       => \$basedir,
+       "kernel|k=s"        => \$kernel,
+       "kernelsyms|F=s"    => \$kernelsyms,
+       "stdout|n"          => \$stdout,
+       "verbose|v"         => \$verbose,
+       "symbol-prefix|P=s" => \$symprefix,
+       "all|a"             => \$all,
+       # unsupported options
+       "quick|A"           => \$quick,
+       # ignored options (for historical usage)
+       "quiet|q",
+       "root|r",
+       "unresolved-error|u"
 );
 
 die $usage if $help;
 die $usage unless $basedir && ( $kernel || $kernelsyms );
 die "can't use both -k and -F\n\n$usage" if $kernel && $kernelsyms;
 );
 
 die $usage if $help;
 die $usage unless $basedir && ( $kernel || $kernelsyms );
 die "can't use both -k and -F\n\n$usage" if $kernel && $kernelsyms;
+die "sorry, -A/--quick is not supported" if $quick;
+die "--errsyms requires --kernelsyms" if $errsyms && !$kernelsyms;
 
 # Strip any trailing or multiple slashes from basedir
 
 # Strip any trailing or multiple slashes from basedir
-$basedir =~ s-(/)\1+-/-g;
+$basedir =~ s-/+$--g;
 
 # The base directory should contain /lib/modules somewhere
 if($basedir !~ m-/lib/modules-) {
 
 # The base directory should contain /lib/modules somewhere
 if($basedir !~ m-/lib/modules-) {
@@ -134,12 +151,55 @@ foreach my $module (keys %$dep) {
     }
 }
 
     }
 }
 
+# build a complete dependency list for each module and make sure it
+# is kept in order proper order
+my $mod2 = {};
+sub maybe_unshift
+{
+       my ($array, $ele) = @_;
+       # chop off the leading path /lib/modules/<kver>/ as modprobe
+       # will handle relative paths just fine
+       $ele =~ s:^/lib/modules/[^/]*/::;
+       foreach (@{$array}) {
+               if ($_ eq $ele) {
+                       return;
+               }
+       }
+       unshift (@{$array}, $ele);
+}
+sub add_mod_deps
+{
+       my ($depth, $mod, $mod2, $module, $this_module) = @_;
+
+       $depth .= " ";
+       warn "${depth}loading deps of module: $this_module\n" if $verbose;
+       if (length($depth) > 50) {
+               die "too much recursion (circular dependencies in modules?)";
+       }
+
+       foreach my $md (keys %{$mod->{$this_module}}) {
+               add_mod_deps ($depth, $mod, $mod2, $module, $md);
+               warn "${depth} outputting $md\n" if $verbose;
+               maybe_unshift (\@{$$mod2->{$module}}, $md);
+       }
+
+       if (!%{$mod->{$this_module}}) {
+               warn "${depth} no deps\n" if $verbose;
+       }
+}
+foreach my $module (keys %$mod) {
+       warn "filling out module: $module\n" if $verbose;
+       @{$mod2->{$module}} = ();
+       add_mod_deps ("", $mod, \$mod2, $module, $module);
+}
+
 # figure out where the output should go
 if ($stdout == 0) {
 # figure out where the output should go
 if ($stdout == 0) {
+       warn "writing $basedir/modules.dep\n" if $verbose;
     open(STDOUT, ">$basedir/modules.dep")
                              or die "cannot open $basedir/modules.dep: $!";
 }
     open(STDOUT, ">$basedir/modules.dep")
                              or die "cannot open $basedir/modules.dep: $!";
 }
-my $kseries = $basedir =~ m,/2\.6\.[^/]*, ? '2.6' : '2.4';
+my $kseries = $basedir =~ m,/2\.4\.[^/]*, ? '2.4' : 'others';
 
 foreach my $module ( keys %$mod ) {
     if($kseries eq '2.4') {
 
 foreach my $module ( keys %$mod ) {
     if($kseries eq '2.4') {
@@ -148,8 +208,11 @@ foreach my $module ( keys %$mod ) {
            print join(" \\\n\t",@sorted);
            print "\n\n";
     } else {
            print join(" \\\n\t",@sorted);
            print "\n\n";
     } else {
-           print "$module: ";
-           my @sorted = sort bydep keys %{$mod->{$module}};
+           my $shortmod = $module;
+           $shortmod =~ s:^/lib/modules/[^/]*/::;
+           print "$shortmod:";
+           my @sorted = @{$mod2->{$module}};
+           printf " " if @sorted;
            print join(" ",@sorted);
            print "\n";
     }
            print join(" ",@sorted);
            print "\n";
     }
@@ -160,21 +223,22 @@ sub build_ref_tables
 {
     my ($name, $sym_ar, $exp, $dep) = @_;
 
 {
     my ($name, $sym_ar, $exp, $dep) = @_;
 
-       my $ksymtab = grep m/ __ksymtab/, @$sym_ar;
+       my $ksymtab = grep m/ ${symprefix}__ksymtab/, @$sym_ar;
 
     # gather the exported symbols
        if($ksymtab){
         # explicitly exported
         foreach ( @$sym_ar ) {
 
     # gather the exported symbols
        if($ksymtab){
         # explicitly exported
         foreach ( @$sym_ar ) {
-            / __ksymtab_(.*)$/ and do {
-                warn "sym = $1\n" if $verbose;
-                $exp->{$1} = $name;
+            / ${symprefix}__ksymtab_(.*)$/ and do {
+                my $sym = ${symprefix} . $1;
+                warn "sym = $sym\n" if $verbose;
+                $exp->{$sym} = $name;
             };
         }
        } else {
         # exporting all symbols
         foreach ( @$sym_ar ) {
             };
         }
        } else {
         # exporting all symbols
         foreach ( @$sym_ar ) {
-            / [ABCDGRST] (.*)$/ and do {
+            / [ABCDGRSTW] (.*)$/ and do {
                 warn "syma = $1\n" if $verbose;
                 $exp->{$1} = $name;
             };
                 warn "syma = $1\n" if $verbose;
                 $exp->{$1} = $name;
             };
@@ -182,11 +246,11 @@ sub build_ref_tables
        }
 
     # this takes makes sure modules with no dependencies get listed
        }
 
     # this takes makes sure modules with no dependencies get listed
-    push @{$dep->{$name}}, 'printk' unless $name eq 'vmlinux';
+    push @{$dep->{$name}}, $symprefix . 'printk' unless $name eq 'vmlinux';
 
     # gather the unresolved symbols
     foreach ( @$sym_ar ) {
 
     # gather the unresolved symbols
     foreach ( @$sym_ar ) {
-        !/ __this_module/ && / U (.*)$/ and do {
+        !/ ${symprefix}__this_module/ && / U (.*)$/ and do {
             warn "und = $1\n" if $verbose;
             push @{$dep->{$name}}, $1;
         };
             warn "und = $1\n" if $verbose;
             push @{$dep->{$name}}, $1;
         };
@@ -211,7 +275,7 @@ __END__
 
 depmod.pl - a cross platform script to generate kernel module
 dependency lists (modules.conf) which can then be used by modprobe
 
 depmod.pl - a cross platform script to generate kernel module
 dependency lists (modules.conf) which can then be used by modprobe
-on the target platform. 
+on the target platform.
 
 It supports Linux 2.4 and 2.6 styles of modules.conf (auto-detected)
 
 
 It supports Linux 2.4 and 2.6 styles of modules.conf (auto-detected)
 
@@ -245,7 +309,7 @@ This displays the help message.
 =item B<-b --basedir>
 
 The base directory uner which the target's modules will be found.  This
 =item B<-b --basedir>
 
 The base directory uner which the target's modules will be found.  This
-defaults to the /lib/modules directory. 
+defaults to the /lib/modules directory.
 
 If you don't specify the kernel version, this script will search for
 one under the specified based directory and use the first thing that
 
 If you don't specify the kernel version, this script will search for
 one under the specified based directory and use the first thing that