summaryrefslogtreecommitdiff
path: root/mkdep.pl
diff options
context:
space:
mode:
Diffstat (limited to 'mkdep.pl')
-rwxr-xr-xmkdep.pl238
1 files changed, 238 insertions, 0 deletions
diff --git a/mkdep.pl b/mkdep.pl
new file mode 100755
index 0000000..9f80ed3
--- /dev/null
+++ b/mkdep.pl
@@ -0,0 +1,238 @@
+#!/usr/bin/perl
+## --------------------------------------------------------------------------
+##
+## Copyright 1996-2009 The NASM Authors - All Rights Reserved
+## See the file AUTHORS included with the NASM distribution for
+## the specific copyright holders.
+##
+## Copyright 1996-2009 the NASM Authors - All rights reserved.
+##
+## Redistribution and use in source and binary forms, with or without
+## modification, are permitted provided that the following
+## conditions are met:
+##
+## * Redistributions of source code must retain the above copyright
+## notice, this list of conditions and the following disclaimer.
+## * Redistributions in binary form must reproduce the above
+## copyright notice, this list of conditions and the following
+## disclaimer in the documentation and/or other materials provided
+## with the distribution.
+##
+## THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
+## CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
+## INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+## MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+## DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+## CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+## SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
+## NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+## LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+## HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+## CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+## OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
+## EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+##
+## --------------------------------------------------------------------------
+
+#
+# Script to create Makefile-style dependencies.
+#
+# Usage: perl mkdep.pl [-s path-separator] [-o obj-ext] 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) = ();
+
+ sysopen(FILE, $file, O_RDONLY)
+ or return; # If not openable, assume generated
+
+ while ( defined($line = <FILE>) ) {
+ chomp $line;
+ $line =~ s:/\*.*\*/::g;
+ $line =~ s://.*$::;
+ if ( $line =~ /^\s*\#\s*include\s+\"(.*)\"\s*$/ ) {
+ $nf = $1;
+ push(@mdeps, $nf);
+ push(@xdeps, $nf) unless ( defined($deps{$nf}) );
+ }
+ }
+ close(FILE);
+ $deps{$file} = [@mdeps];
+
+ foreach $file ( @xdeps ) {
+ scandeps($file);
+ }
+}
+
+# %deps contains direct dependencies. This subroutine resolves
+# indirect dependencies that result.
+sub alldeps($) {
+ my($file) = @_;
+ my(%adeps);
+ my($dep,$idep);
+
+ foreach $dep ( @{$deps{$file}} ) {
+ $adeps{$dep} = 1;
+ foreach $idep ( alldeps($dep) ) {
+ $adeps{$idep} = 1;
+ }
+ }
+ return sort(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));
+ }
+
+ if ( $sep eq '' ) {
+ # This means kill path completely. Used with Makes who do
+ # path searches, but doesn't handle output files in subdirectories,
+ # like OpenWatcom WMAKE.
+ return $fspec[scalar(@fspec)-1];
+ } else {
+ 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) = '/';
+ my($cont) = "\\";
+ my($maxline) = 78; # Seems like a reasonable default
+ my @exclude = (); # Don't exclude anything
+
+ 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 ( $parm eq 'line-width' ) {
+ $maxline = $val+0;
+ } elsif ( $parm eq 'continuation' ) {
+ $cont = $val;
+ } elsif ( $parm eq 'exclude' ) {
+ @exclude = split(/\,/, $val);
+ }
+ } elsif ( $line eq $barrier ) {
+ last; # Stop reading input at barrier line
+ }
+ print OUT $line;
+ }
+ close(IN);
+
+ my $e;
+ my %do_exclude = ();
+ foreach $e (@exclude) {
+ $do_exclude{$e} = 1;
+ }
+
+ my $dfile, $ofile, $str, $sl, $len;
+ my @deps, $dep;
+
+ print OUT $barrier;
+
+ foreach $dfile ( sort(keys(%deps)) ) {
+ if ( $dfile =~ /\.[Cc]$/ ) {
+ $ofile = $dfile; $ofile =~ s/\.[Cc]$//;
+ $str = convert_file($ofile,$sep).$obj.':';
+ $len = length($str);
+ print OUT $str;
+ foreach $dep ($dfile, alldeps($dfile)) {
+ unless ($do_exclude{$dep}) {
+ $str = convert_file($dep,$sep);
+ $sl = length($str)+1;
+ if ( $len+$sl > $maxline-2 ) {
+ print OUT ' ', $cont, "\n ", $str;
+ $len = $sl;
+ } else {
+ print OUT ' ', $str;
+ $len += $sl;
+ }
+ }
+ }
+ print OUT "\n";
+ }
+ }
+ close(OUT);
+
+ (unlink($file) && rename($tmp, $file))
+ or die "$0: Failed to change $tmp -> $file\n";
+}
+
+#
+# Main program
+#
+
+%deps = ();
+@files = ();
+@mkfiles = ();
+$mkmode = 0;
+
+while ( defined($arg = shift(@ARGV)) ) {
+ if ( $arg eq '-m' ) {
+ $arg = shift(@ARGV);
+ push(@mkfiles, $arg);
+ } elsif ( $arg eq '-M' ) {
+ $mkmode = 1; # Futher filenames are output Makefile names
+ } elsif ( $arg eq '--' && $mkmode ) {
+ $mkmode = 0;
+ } elsif ( $arg =~ /^-/ ) {
+ die "Unknown option: $arg\n";
+ } else {
+ if ( $mkmode ) {
+ push(@mkfiles, $arg);
+ } else {
+ push(@files, $arg);
+ }
+ }
+}
+
+foreach $dir ( @files ) {
+ opendir(DIR, $dir) or die "$0: Cannot open directory: $dir";
+
+ while ( $file = readdir(DIR) ) {
+ $path = ($dir eq File::Spec->curdir())
+ ? $file : File::Spec->catfile($dir,$file);
+ if ( $file =~ /\.[Cc]$/ ) {
+ scandeps($path);
+ }
+ }
+ closedir(DIR);
+}
+
+foreach $mkfile ( @mkfiles ) {
+ insert_deps($mkfile);
+}