Annotation of embedaddon/sudo/mkdep.pl, revision 1.1
1.1 ! misho 1: #!/usr/bin/env perl
! 2:
! 3: use File::Temp qw/ :mktemp /;
! 4: use Fcntl;
! 5: use warnings;
! 6:
! 7: die "usage: $0 Makefile ...\n" unless $#ARGV >= 0;
! 8:
! 9: my @incpaths;
! 10: my %dir_vars;
! 11: my %implicit;
! 12:
! 13: # Read in MANIFEST fail if present
! 14: my %manifest;
! 15: if (open(MANIFEST, "<MANIFEST")) {
! 16: while (<MANIFEST>) {
! 17: chomp;
! 18: next unless /([^\/]+\.[cly])$/;
! 19: $manifest{$1} = $_;
! 20: }
! 21: }
! 22:
! 23: foreach (@ARGV) {
! 24: mkdep($_);
! 25: }
! 26:
! 27: sub mkdep {
! 28: my $file = $_[0];
! 29: $file =~ s:^\./+::; # strip off leading ./
! 30:
! 31: my $makefile;
! 32: if (open(MF, "<$file")) {
! 33: local $/; # enable "slurp" mode
! 34: $makefile = <MF>;
! 35: } else {
! 36: warn "$0: $file: $!\n";
! 37: return undef;
! 38: }
! 39: close(MF);
! 40:
! 41: # New makefile, minus the autogenerated dependencies
! 42: my $separator = "# Autogenerated dependencies, do not modify";
! 43: my $new_makefile = $makefile;
! 44: $new_makefile =~ s/${separator}.*$//s;
! 45: $new_makefile .= "$separator\n";
! 46:
! 47: # Old makefile, join lines with continuation characters
! 48: $makefile =~ s/\\\n//mg;
! 49:
! 50: # Expand some configure bits
! 51: $makefile =~ s:\@COMMON_OBJS\@:aix.lo:;
! 52: $makefile =~ s:\@SUDO_OBJS\@:preload.o selinux.o sesh.o sudo_noexec.lo:;
! 53: $makefile =~ s:\@SUDOERS_OBJS\@:bsm_audit.lo linux_audit.lo ldap.lo plugin_error.lo:;
! 54: # XXX - fill in AUTH_OBJS from contents of the auth dir instead
! 55: $makefile =~ s:\@AUTH_OBJS\@:afs.lo aix_auth.lo bsdauth.lo dce.lo fwtk.lo getspwuid.lo kerb4.lo kerb5.lo pam.lo passwd.lo rfc1938.lo secureware.lo securid.lo securid5.lo sia.lo:;
! 56: $makefile =~ s:\@LTLIBOBJS\@:closefrom.lo dlopen.lo fnmatch.lo getcwd.lo getgrouplist.lo getline.lo getprogname.lo glob.lo isblank.lo memrchr.lo mksiglist.lo mktemp.lo nanosleep.lo setenv.lo siglist.lo snprintf.lo strlcat.lo strlcpy.lo strsignal.lo unsetenv.lo utimes.lo globtest.o fnm_test.o:;
! 57:
! 58: # Parse OBJS lines
! 59: my %objs;
! 60: while ($makefile =~ /^[A-Z0-9_]*OBJS\s*=\s*(.*)/mg) {
! 61: foreach (split/\s+/, $1) {
! 62: next if /^\$[\(\{].*[\)\}]$/; # skip included vars for now
! 63: $objs{$_} = 1;
! 64: }
! 65: }
! 66:
! 67: # Find include paths
! 68: @incpaths = ();
! 69: while ($makefile =~ /-I(\S+)/mg) {
! 70: push(@incpaths, $1) unless $1 eq ".";
! 71: }
! 72:
! 73: # Values of srcdir, top_srcdir, top_builddir, incdir
! 74: %dir_vars = ();
! 75: $file =~ m:^(.*)/+[^/]+:;
! 76: $dir_vars{'srcdir'} = $1 || '.';
! 77: $dir_vars{'devdir'} = $dir_vars{'srcdir'};
! 78: $dir_vars{'authdir'} = $dir_vars{'srcdir'} . "/auth";
! 79: $dir_vars{'top_srcdir'} = '.';
! 80: #$dir_vars{'top_builddir'} = '.';
! 81: $dir_vars{'incdir'} = 'include';
! 82:
! 83: # Find implicit rules for generate .o and .lo files
! 84: %implicit = ();
! 85: while ($makefile =~ /^\.c\.(l?o):\s*\n\t+(.*)$/mg) {
! 86: $implicit{$1} = $2;
! 87: }
! 88:
! 89: # Find existing .o and .lo dependencies
! 90: my %old_deps;
! 91: while ($makefile =~ /^(\w+\.l?o):\s*(\S+\.c)/mg) {
! 92: $old_deps{$1} = $2;
! 93: }
! 94:
! 95: # Sort files so we do .lo files first
! 96: foreach my $obj (sort keys %objs) {
! 97: next unless $obj =~ /(\S+)\.(l?o)$/;
! 98: if ($2 eq "o" && exists($objs{"$1.lo"})) {
! 99: # If we have both .lo and .o files, make the .o depend on the .lo
! 100: $new_makefile .= sprintf("%s: %s.lo\n", $obj, $1);
! 101: } else {
! 102: # Use old depenencies when mapping objects to their source.
! 103: # If no old depenency, use the MANIFEST file to find the source.
! 104: my $src = $1 . '.c';
! 105: my $ext = $2;
! 106: if (exists $old_deps{$obj}) {
! 107: $src = $old_deps{$obj};
! 108: } elsif (exists $manifest{$src}) {
! 109: $src = $manifest{$src};
! 110: foreach (sort { length($b) <=> length($a) } keys %dir_vars) {
! 111: last if $src =~ s:^\Q$dir_vars{$_}/\E:\$\($_\)/:;
! 112: }
! 113: } else {
! 114: warn "$file: unable to find source for $obj\n";
! 115: }
! 116: my $imp = $implicit{$ext};
! 117: $imp =~ s/\$</$src/g;
! 118:
! 119: my $deps = sprintf("%s: %s %s", $obj, $src,
! 120: join(' ', find_depends($src)));
! 121: if (length($deps) > 80) {
! 122: my $off = 0;
! 123: my $indent = length($obj) + 2;
! 124: while (length($deps) - $off > 80 - $indent) {
! 125: my $pos;
! 126: if ($off != 0) {
! 127: $new_makefile .= ' ' x $indent;
! 128: $pos = rindex($deps, ' ', $off + 80 - $indent - 2);
! 129: } else {
! 130: $pos = rindex($deps, ' ', $off + 78);
! 131: }
! 132: $new_makefile .= substr($deps, $off, $pos - $off) . " \\\n";
! 133: $off = $pos + 1;
! 134: }
! 135: $new_makefile .= ' ' x $indent;
! 136: $new_makefile .= substr($deps, $off) . "\n";
! 137: } else {
! 138: $new_makefile .= "$deps\n";
! 139: }
! 140: $new_makefile .= "\t$imp\n";
! 141: }
! 142: }
! 143:
! 144: rename($file, $file . ".old");
! 145: if (!open(MF, ">$file")) {
! 146: warn("cannot open $file: $!\n");
! 147: rename($file . ".old", $file);
! 148: } else {
! 149: print MF $new_makefile || warn("cannot write $file: $!\n");
! 150: close(MF);
! 151: }
! 152: }
! 153:
! 154: exit(0);
! 155:
! 156: sub find_depends {
! 157: my $src = $_[0];
! 158: my ($deps, $code, @headers);
! 159:
! 160: if ($src !~ /\//) {
! 161: # XXX - want build dir not src dir
! 162: $src = "$dir_vars{'srcdir'}/$src";
! 163: }
! 164:
! 165: # resolve $(srcdir) etc.
! 166: foreach (keys %dir_vars) {
! 167: $src =~ s/\$[\(\{]$_[\)\}]/$dir_vars{$_}/g;
! 168: }
! 169:
! 170: # find open source file and find headers used by it
! 171: if (!open(FILE, "<$src")) {
! 172: warn "unable to open $src\n";
! 173: return "";
! 174: }
! 175: local $/; # enable "slurp" mode
! 176: $code = <FILE>;
! 177: close(FILE);
! 178:
! 179: # find all headers
! 180: while ($code =~ /^#\s*include\s+["<](\S+)[">]/mg) {
! 181: my ($hdr, $hdr_path) = find_header($1);
! 182: if (defined($hdr)) {
! 183: push(@headers, $hdr);
! 184: # Look for other includes in the .h file
! 185: push(@headers, find_depends($hdr_path));
! 186: }
! 187: }
! 188:
! 189: @headers;
! 190: }
! 191:
! 192: # find the path to a header file
! 193: # returns path or undef if not found
! 194: sub find_header {
! 195: my $hdr = $_[0];
! 196:
! 197: # Look for .h.in files in top_builddir and build dir
! 198: return ("\$(top_builddir\)/$hdr", "./${hdr}.in") if -r "./${hdr}.in";
! 199: return ("./$hdr", "$dir_vars{'srcdir'}/${hdr}.in") if -r "$dir_vars{'srcdir'}/${hdr}.in";
! 200:
! 201: foreach my $inc (@incpaths) {
! 202: my $hdr_path = "$inc/$hdr";
! 203: # resolve variables in include path
! 204: foreach (keys %dir_vars) {
! 205: $hdr_path =~ s/\$[\(\{]$_[\)\}]/$dir_vars{$_}/g;
! 206: }
! 207: return ("$inc/$hdr", $hdr_path) if -r $hdr_path;
! 208: }
! 209:
! 210: undef;
! 211: }
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>