| 1 | #!../perl |
| 2 | |
| 3 | $M = '-M'; |
| 4 | $M = '-m' if -d '/usr/uts' && -f '/etc/master'; |
| 5 | |
| 6 | do 'getopt.pl'; |
| 7 | do Getopt('f'); |
| 8 | |
| 9 | if ($opt_f) { |
| 10 | $makefile = $opt_f; |
| 11 | } |
| 12 | elsif (-f 'makefile') { |
| 13 | $makefile = 'makefile'; |
| 14 | } |
| 15 | elsif (-f 'Makefile') { |
| 16 | $makefile = 'Makefile'; |
| 17 | } |
| 18 | else { |
| 19 | die "No makefile\n"; |
| 20 | } |
| 21 | |
| 22 | $MF = 'mf00'; |
| 23 | |
| 24 | while(($key,$val) = each(ENV)) { |
| 25 | $mac{$key} = $val; |
| 26 | } |
| 27 | |
| 28 | do scan($makefile); |
| 29 | |
| 30 | $co = $action{'.c.o'}; |
| 31 | $co = ' ' unless $co; |
| 32 | |
| 33 | $missing = "Missing dependencies:\n"; |
| 34 | foreach $key (sort keys(o)) { |
| 35 | if ($oc{$key}) { |
| 36 | $src = $oc{$key}; |
| 37 | $action = $action{$key}; |
| 38 | } |
| 39 | else { |
| 40 | $action = ''; |
| 41 | } |
| 42 | if (!$action) { |
| 43 | if ($co && ($c = $key) =~ s/\.o$/.c/ && -f $c) { |
| 44 | $src = $c; |
| 45 | $action = $co; |
| 46 | } |
| 47 | else { |
| 48 | print "No source found for $key $c\n"; |
| 49 | next; |
| 50 | } |
| 51 | } |
| 52 | $I = ''; |
| 53 | $D = ''; |
| 54 | $I .= $1 while $action =~ s/(-I\S+\s*)//; |
| 55 | $D .= $1 . ' ' while $action =~ s/(-D\w+)//; |
| 56 | if ($opt_v) { |
| 57 | $cmd = "Checking $key: cc $M $D $I $src"; |
| 58 | $cmd =~ s/\s\s+/ /g; |
| 59 | print stderr $cmd,"\n"; |
| 60 | } |
| 61 | open(CPP,"cc $M $D $I $src|") || die "Can't run C preprocessor: $!"; |
| 62 | while (<CPP>) { |
| 63 | ($name,$dep) = split; |
| 64 | $dep =~ s|^\./||; |
| 65 | (print $missing,"$key: $dep\n"),($missing='') |
| 66 | unless ($dep{"$key: $dep"} += 2) > 2; |
| 67 | } |
| 68 | } |
| 69 | |
| 70 | $extra = "\nExtraneous dependencies:\n"; |
| 71 | foreach $key (sort keys(dep)) { |
| 72 | if ($key =~ /\.o: .*\.h$/ && $dep{$key} == 1) { |
| 73 | print $extra,$key,"\n"; |
| 74 | $extra = ''; |
| 75 | } |
| 76 | } |
| 77 | |
| 78 | sub scan { |
| 79 | local($makefile) = @_; |
| 80 | local($MF) = $MF; |
| 81 | print stderr "Analyzing $makefile.\n" if $opt_v; |
| 82 | $MF++; |
| 83 | open($MF,$makefile) || die "Can't open $makefile: $!"; |
| 84 | while (<$MF>) { |
| 85 | chop; |
| 86 | chop($_ = $_ . <$MF>) while s/\\$//; |
| 87 | next if /^#/; |
| 88 | next if /^$/; |
| 89 | s/\$\((\w+):([^=)]*)=([^)]*)\)/do subst("$1","$2","$3")/eg; |
| 90 | s/\$\((\w+)\)/$mac{$1}/eg; |
| 91 | $mac{$1} = $2, next if /^(\w+)\s*=\s*(.*)/; |
| 92 | if (/^include\s+(.*)/) { |
| 93 | do scan($1); |
| 94 | print stderr "Continuing $makefile.\n" if $opt_v; |
| 95 | next; |
| 96 | } |
| 97 | if (/^([^:]+):\s*(.*)/) { |
| 98 | $left = $1; |
| 99 | $right = $2; |
| 100 | if ($right =~ /^([^;]*);(.*)/) { |
| 101 | $right = $1; |
| 102 | $action = $2; |
| 103 | } |
| 104 | else { |
| 105 | $action = ''; |
| 106 | } |
| 107 | while (<$MF>) { |
| 108 | last unless /^\t/; |
| 109 | chop; |
| 110 | chop($_ = $_ . <$MF>) while s/\\$//; |
| 111 | next if /^#/; |
| 112 | last if /^$/; |
| 113 | s/\$\((\w+):([^=)]*)=([^)]*)\)/do subst("$1","$2","$3")/eg; |
| 114 | s/\$\((\w+)\)/$mac{$1}/eg; |
| 115 | $action .= $_; |
| 116 | } |
| 117 | foreach $targ (split(' ',$left)) { |
| 118 | $targ =~ s|^\./||; |
| 119 | foreach $src (split(' ',$right)) { |
| 120 | $src =~ s|^\./||; |
| 121 | $deplist{$targ} .= ' ' . $src; |
| 122 | $dep{"$targ: $src"} = 1; |
| 123 | $o{$src} = 1 if $src =~ /\.o$/; |
| 124 | $oc{$targ} = $src if $targ =~ /\.o$/ && $src =~ /\.[yc]$/; |
| 125 | } |
| 126 | $action{$targ} .= $action; |
| 127 | } |
| 128 | redo if $_; |
| 129 | } |
| 130 | } |
| 131 | close($MF); |
| 132 | } |
| 133 | |
| 134 | sub subst { |
| 135 | local($foo,$from,$to) = @_; |
| 136 | $foo = $mac{$foo}; |
| 137 | $from =~ s/\./[.]/; |
| 138 | y/a/a/; |
| 139 | $foo =~ s/\b$from\b/$to/g; |
| 140 | $foo; |
| 141 | } |