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>