mirror of
https://github.com/netwide-assembler/nasm.git
synced 2025-01-18 16:25:05 +08:00
ab8447ed99
For the canned makefiles, we almost certainly don't have config.h, and shouldn't include it in the list of dependencies.
203 lines
4.5 KiB
Perl
Executable File
203 lines
4.5 KiB
Perl
Executable File
#!/usr/bin/perl
|
|
#
|
|
# 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, %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);
|
|
}
|