GenLibDeps.pl revision 444b2cf4c3718da8d2b38344ca3d8e50aa9d9538
1#!/usr/bin/perl -w 2# 3# Program: GenLibDeps.pl 4# 5# Synopsis: Generate HTML output that shows the dependencies between a set of 6# libraries. The output of this script should periodically replace 7# the similar content in the UsingLibraries.html document. 8# 9# Syntax: GenLibDeps.pl <directory_with_libraries_in_it> 10# 11 12# Parse arguments... 13while (scalar(@ARGV) and ($_ = $ARGV[0], /^[-+]/)) { 14 shift; 15 last if /^--$/; # Stop processing arguments on -- 16 17 # List command line options here... 18 if (/^-flat$/) { $FLAT = 1; next; } 19 print "Unknown option: $_ : ignoring!\n"; 20} 21 22# Give first option a name. 23my $Directory = $ARGV[0]; 24 25# Find the "dot" program 26if (!$FLAT) { 27 chomp(my $DotPath = `which dot`); 28 die "Can't find 'dot'" if (! -x "$DotPath"); 29} 30 31# Open the directory and read its contents, sorting by name and differentiating 32# by whether its a library (.a) or an object file (.o) 33opendir DIR,$Directory; 34my @files = readdir DIR; 35closedir DIR; 36@libs = grep(/libLLVM.*\.a$/,sort(@files)); 37@objs = grep(/LLVM.*\.o$/,sort(@files)); 38 39# Declare the hashes we will use to keep track of the library and object file 40# symbol definitions. 41my %libdefs; 42my %objdefs; 43 44# Gather definitions from the libraries 45foreach $lib (@libs ) { 46 open DEFS, 47 "nm -g $Directory/$lib | grep ' [ABCDGRST] ' | sed -e 's/^[0-9A-Fa-f]* [ABCDGRST] //' | sort | uniq |"; 48 while (<DEFS>) { 49 chomp($_); 50 $libdefs{$_} = $lib; 51 } 52 close DEFS; 53} 54 55# Gather definitions from the object files. 56foreach $obj (@objs ) { 57 open DEFS, 58 "nm -g $Directory/$obj | grep ' [ABCDGRST] ' | sed -e 's/^[0-9A-Fa-f]* [ABCDGRST] //' | sort | uniq |"; 59 while (<DEFS>) { 60 chomp($_); 61 $objdefs{$_} = $obj; 62 } 63 close DEFS; 64} 65 66# Generate one entry in the <dl> list. This generates the <dt> and <dd> elements 67# for one library or object file. The <dt> provides the name of the library or 68# object. The <dd> provides a list of the libraries/objects it depends on. 69sub gen_one_entry { 70 my $lib = $_[0]; 71 my $lib_ns = $lib; 72 $lib_ns =~ s/(.*)\.[oa]/$1/; 73 if ($FLAT) { 74 print "$lib:"; 75 } else { 76 print " <dt><b>$lib</b</dt><dd><ul>\n"; 77 } 78 open UNDEFS, 79 "nm -g -u $Directory/$lib | grep ' U ' | sed -e 's/ U //' | sort | uniq |"; 80 open DEPENDS, 81 "| sort | uniq > GenLibDeps.out"; 82 while (<UNDEFS>) { 83 chomp; 84 if (defined($libdefs{$_}) && $libdefs{$_} ne $lib) { 85 print DEPENDS "$libdefs{$_}\n"; 86 } elsif (defined($objdefs{$_}) && $objdefs{$_} ne $lib) { 87 $libroot = $lib; 88 $libroot =~ s/lib(.*).a/$1/; 89 if ($objdefs{$_} ne "$libroot.o") { 90 print DEPENDS "$objdefs{$_}\n"; 91 } 92 } 93 } 94 close UNDEFS; 95 close DEPENDS; 96 open DF, "<GenLibDeps.out"; 97 while (<DF>) { 98 chomp; 99 if ($FLAT) { 100 print " $_"; 101 } else { 102 print " <li>$_</li>\n"; 103 } 104 $suffix = substr($_,length($_)-1,1); 105 $_ =~ s/(.*)\.[oa]/$1/; 106 if ($suffix eq "a") { 107 if (!$FLAT) { print DOT "$lib_ns -> $_ [ weight=0 ];\n" }; 108 } else { 109 if (!$FLAT) { print DOT "$lib_ns -> $_ [ weight=10];\n" }; 110 } 111 } 112 close DF; 113 if ($FLAT) { 114 print "\n"; 115 } else { 116 print " </ul></dd>\n"; 117 } 118} 119 120# Make sure we flush on write. This is slower but correct based on the way we 121# write I/O in gen_one_entry. 122$| = 1; 123 124# Print the definition list tag 125if (!$FLAT) { 126 print "<dl>\n"; 127 128 open DOT, "| $DotPath -Tgif > libdeps.gif"; 129 130 print DOT "digraph LibDeps {size=\"40,15\"; ratio=\"1.33333\"; margin=\"0.25\"; rankdir=\"LR\"; mclimit=\"50.0\"; ordering=\"out\"; center=\"1\";\n"; 131 print DOT "node [shape=\"box\",color=\"#000088\",fillcolor=\"#FFFACD\",fontcolor=\"#5577DD\",style=\"filled\",fontsize=\"24\"];\n"; 132 print DOT "edge [style=\"solid\",color=\"#000088\"];\n"; 133} 134 135# Print libraries first 136foreach $lib (@libs) { 137 gen_one_entry($lib); 138} 139 140if (!$FLAT) { 141 print DOT "}\n"; 142 close DOT; 143 open DOT, "| $DotPath -Tgif > objdeps.gif"; 144 print DOT "digraph ObjDeps {size=\"40,15\"; ratio=\"1.33333\"; margin=\"0.25\"; rankdir=\"LR\"; mclimit=\"50.0\"; ordering=\"out\"; center=\"1\";\n"; 145 print DOT "node [shape=\"box\",color=\"#000088\",fillcolor=\"#FFFACD\",fontcolor=\"#5577DD\",style=\"filled\",fontsize=\"24\"];\n"; 146 print DOT "edge [style=\"solid\",color=\"#000088\"];\n"; 147} 148 149# Print objects second 150foreach $obj (@objs) { 151 gen_one_entry($obj); 152} 153 154if (!$FLAT) { 155 print DOT "}\n"; 156 close DOT; 157 158# Print end tag of definition list element 159 print "</dl>\n"; 160} 161