]> jfr.im git - irc/quakenet/newserv.git/blob - depmod.pl
Merge default.
[irc/quakenet/newserv.git] / depmod.pl
1 #!/usr/bin/perl -w
2
3 use strict;
4
5 my $verbose=0;
6
7 my %definers;
8 my %reqsyms;
9 my %reqmods;
10 my %printed;
11
12 my @arglist = <*.so>;
13 #push @arglist, "../newserv";
14 my @realarglist;
15
16 open DEPENDS,">modules.dep";
17 open GRAPH,">modgraph.dot";
18
19 if (@ARGV) {
20 if ($ARGV[0] eq "--verbose" or $ARGV[0] eq "-v") {
21 $verbose=1;
22 }
23 }
24
25 for (@arglist) {
26 my $modname=$_;
27 open NM,"nm $modname |";
28
29 $modname =~ s/.so$//;
30
31 push @realarglist, $modname;
32
33 $reqsyms{$modname} = [];
34
35 while (<NM>) {
36 chomp;
37 next unless (/([URTB]) (\S+)/);
38
39 my ($type,$sym) = ($1, $2);
40
41 next if ($sym eq "_init");
42 next if ($sym eq "_fini");
43 next if ($sym eq "_version");
44
45 if ($type eq "U") {
46 push @{$reqsyms{$modname}}, $sym;
47 } else {
48 if (defined $definers{$sym}) {
49 print "WARNING: Multiple modules export $sym, at least $modname and $definers{$sym}\n";
50 } else {
51 $definers{$sym}=$modname;
52 }
53 }
54 }
55
56 close NM;
57 }
58
59 print GRAPH "digraph g { \n";
60
61 for (@realarglist) {
62 my $modname=$_;
63
64 $reqmods{$modname} = {};
65
66 for (@{$reqsyms{$modname}}) {
67 my $provider = $definers{$_};
68
69 if (defined $provider) {
70 ${reqmods{$modname}}{$provider}=1;
71 if ($verbose) {
72 print "Module $modname importing $_ from $provider\n";
73 }
74 }
75 }
76 }
77
78 for (@realarglist) {
79 printdep($_);
80 }
81
82 print GRAPH "}\n";
83
84 close GRAPH;
85 close DEPENDS;
86
87 sub printdep {
88 my ($modname) = @_;
89
90 if (!(defined $printed{$modname})) {
91 $printed{$modname}=1;
92
93 for (keys %{$reqmods{$modname}}) {
94 printdep($_);
95 }
96
97 print DEPENDS "$modname";
98 for (keys %{$reqmods{$modname}}) {
99 if (defined ${$reqmods{$_}}{$modname}) {
100 print "ERROR: circular dependency between $modname and $_\n";
101 }
102 print DEPENDS " $_";
103 print GRAPH "\t\"$modname\" -> \"$_\";\n";
104 }
105 print DEPENDS "\n";
106 }
107 }