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