Support generating dependencies in different syntaxes.
authorH. Peter Anvin <hpa@zytor.com>
Tue, 4 Jun 2002 00:26:13 +0000 (00:26 +0000)
committerH. Peter Anvin <hpa@zytor.com>
Tue, 4 Jun 2002 00:26:13 +0000 (00:26 +0000)
mkdep.pl

index 69743f6..1385d84 100755 (executable)
--- a/mkdep.pl
+++ b/mkdep.pl
@@ -5,13 +5,24 @@
 # Usage: perl [-s path-separator] [-o obj-ext] mkdep.pl dir... > deps
 #
 
+use File::Spec;
+use File::Basename;
+use Fcntl;
+
+$barrier = "#-- Everything below is generated by mkdep.pl - do not edit --#\n";
+
+#
+# Scan files for dependencies
+#
 sub scandeps($) {
     my($file) = @_;
     my($line, $nf);
     my(@xdeps) = ();
     my(@mdeps) = ();
 
-    open(FILE, "< $file\0") or return; # If not openable, assume generated
+    sysopen(FILE, $file, O_RDONLY)
+       or return;              # If not openable, assume generated
+
     while ( defined($line = <FILE>) ) {
        chomp $line;
        $line =~ s:/\*.*\*/::g;
@@ -46,16 +57,84 @@ sub alldeps($) {
     return keys(%adeps);
 }
 
+# This converts a filename from host syntax to target syntax
+# This almost certainly works only on relative filenames...
+sub convert_file($$) {
+    my($file,$sep) = @_;
+    my(@fspec) = (basename($file));
+    while ( ($file = dirname($file)) ne File::Spec->curdir() &&
+           $file ne File::Spec->rootdir() ) {
+       unshift(@fspec, basename($file));
+    }
+
+    return join($sep, @fspec);
+}
+
+#
+# Insert dependencies into a Makefile
+#
+sub insert_deps($) {
+    my($file) = @_;
+    $nexttemp++;               # Unique serial number for each temp file
+    my($tmp) = File::Spec->catfile(dirname($file), 'tmp.'.$nexttemp);
+    
+    sysopen(IN, $file, O_RDONLY)
+       or die "$0: Cannot open input: $file\n";
+    sysopen(OUT, $tmp, O_WRONLY|O_CREAT|O_TRUNC, 0666)
+       or die "$0: Cannot open output: $tmp\n";
+
+    my($line,$parm,$val);
+    my($obj) = '.o';           # Defaults
+    my($sep) = '/';
+
+    while ( defined($line = <IN>) ) {
+       if ( $line =~ /^\s*\#\s*@([a-z0-9-]+):\s*\"([^\"]*)\"/ ) {
+           $parm = $1;  $val = $2;
+           if ( $parm eq 'object-ending' ) {
+               $obj = $val;
+           } elsif ( $parm eq 'path-separator' ) {
+               $sep = $val;
+           }
+       } elsif ( $line eq $barrier ) {
+           last;               # Stop reading input at barrier line
+       }
+       print OUT $line;
+    }
+    close(IN);
+
+    my $dfile, $ofile;
+    my @deps, $dep;
+
+    print OUT $barrier;
+
+    foreach $dfile ( sort(keys(%deps)) ) {
+       if ( $dfile =~ /\.[Cc]$/ ) {
+           $ofile = $dfile; $ofile =~ s/\.[Cc]$//;
+           print OUT convert_file($ofile,$sep), $obj, ':';
+           foreach $dep ($dfile, alldeps($dfile)) {
+               print OUT ' ', convert_file($dep,$sep);
+           }
+           print OUT "\n";
+       }
+    }
+    close(OUT);
+    
+    (unlink($file) && rename($tmp, $file)) 
+       or die "$0: Failed to change $tmp -> $file\n";
+}
+
+#
+# Main program
+#
+    
 %deps = ();
 @files = ();
-$sep = '/';                    # Default, and works on most systems
-$obj = 'o';                    # Object file extension
+@mkfiles = ();
 
 while ( defined($arg = shift(@ARGV)) ) {
-    if ( $arg =~ /^\-s$/ ) {
-       $sep = shift(@ARGV);
-    } elsif ( $arg =~ /^\-o$/ ) {
-       $obj = shift(@ARGV);
+    if ( $arg eq '-m' ) {
+       $arg = shift(@ARGV);
+       push(@mkfiles, $arg);
     } elsif ( $arg =~ /^-/ ) {
        die "Unknown option: $arg\n";
     } else {
@@ -67,7 +146,8 @@ foreach $dir ( @files ) {
     opendir(DIR, $dir) or die "$0: Cannot open directory: $dir";
 
     while ( $file = readdir(DIR) ) {
-       $path = ($dir eq '.') ? $file : $dir.$sep.$file;
+       $path = ($dir eq File::Spec->curdir())
+           ? $file : File::Spec->catfile($dir,$file);
        if ( $file =~ /\.[Cc]$/ ) {
            scandeps($path);
        }
@@ -75,12 +155,6 @@ foreach $dir ( @files ) {
     closedir(DIR);
 }
 
-foreach $file ( sort(keys(%deps)) ) {
-    if ( $file =~ /\.[Cc]$/ ) {
-       $ofile = $file; $ofile =~ s/\.[Cc]$/\./; $ofile .= $obj;
-       print $ofile, ': ', $file, ' ';
-       print join(' ', alldeps($file));
-       print "\n";
-    }
+foreach $mkfile ( @mkfiles ) {
+    insert_deps($mkfile);
 }
-