# 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;
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 {
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);
}
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);
}
-