Make dependency generation a bit more robust

Improve the corner cases where we might end up with bogus
dependencies.

Signed-off-by: H. Peter Anvin <hpa@zytor.com>
This commit is contained in:
H. Peter Anvin 2017-11-06 22:37:37 -08:00
parent ad4016952d
commit ceeaf11e66
4 changed files with 98 additions and 51 deletions

View File

@ -66,6 +66,7 @@ ifeq ($(TRACE),1)
CFLAGS += -DNASM_TRACE
endif
.SUFFIXES:
.SUFFIXES: .c .i .s .$(O) .$(A) $(X) .1 .txt .xml
.PHONY: all doc rdf install clean distclean cleaner spotless install_rdf test
@ -87,10 +88,6 @@ endif
.xml.1:
$(XMLTO) man --skip-validation $< 2>/dev/null
# This rule is only used for rdoff, to allow common rules
.$(O)$(X):
$(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $< $(RDFLIB) $(NASMLIB) $(LIBS)
#-- Begin File Lists --#
NASM = asm/nasm.$(O)
NDISASM = disasm/ndisasm.$(O)
@ -291,11 +288,19 @@ RDF2BINLINKS = rdoff/rdf2com$(X) rdoff/rdf2ith$(X) \
RDFLIB = rdoff/librdoff.$(A)
RDFLIBS = $(RDFLIB) $(NASMLIB)
# This rule is only used for rdoff, to allow common rules
MAKERDF = $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $< $(RDFLIB) $(NASMLIB) $(LIBS)
rdoff/rdfdump$(X): rdoff/rdfdump.$(O) $(RDFLIBS)
$(MAKERDF)
rdoff/ldrdf$(X): rdoff/ldrdf.$(O) $(RDFLIBS)
$(MAKERDF)
rdoff/rdx$(X): rdoff/rdx.$(O) $(RDFLIBS)
$(MAKERDF)
rdoff/rdflib$(X): rdoff/rdflib.$(O) $(RDFLIBS)
$(MAKERDF)
rdoff/rdf2bin$(X): rdoff/rdf2bin.$(O) $(RDFLIBS)
$(MAKERDF)
rdoff/rdf2com$(X): rdoff/rdf2bin$(X)
$(RM_F) rdoff/rdf2com$(X)
cd rdoff && $(LN_S) rdf2bin$(X) rdf2com$(X)
@ -357,16 +362,17 @@ clean:
distclean: clean
$(RM_F) config.log config.status config/config.h
$(RM_F) Makefile
for d in . $(SUBDIRS) $(XSUBDIRS); do \
$(RM_F) "$$d"/*~ "$$d"/*.bak "$$d"/*.lst "$$d"/*.bin ; \
done
$(RM_F) test/*.$(O)
$(RM_RF) autom4te*.cache
$(RM_F) Makefile *.dep
cleaner: clean
$(RM_F) $(PERLREQ) *.1 nasm.spec
$(MAKE) -C doc clean
$(RM_F) *.dep
spotless: distclean cleaner
$(RM_F) doc/Makefile
@ -442,6 +448,24 @@ test: nasm$(X)
golden: nasm$(X)
cd test && $(RUNPERL) performtest.pl --golden --nasm=../nasm *.asm
#
# Rules to re-run autoconf if necessary
#
config/config.h.in: configure.ac
autoheader
configure: configure.ac config/config.h.in
autoconf
config.status: configure Makefile.in doc/Makefile.in config/config.h.in
sh config.status --recheck
Makefile: config.status
doc/Makefile: config.status
config/config.h: config.status
#
# Does this version of this file have external dependencies? This definition
# will be automatically updated by mkdep.pl as needed.
@ -454,38 +478,44 @@ EXTERNAL_DEPENDENCIES = 1
# the dependency information will remain external, so it doesn't
# pollute the git logs.
#
deps: perlreq tools/mkdep.pl
Makefile.dep: $(PERLREQ) tools/mkdep.pl config.status
$(RUNPERL) tools/mkdep.pl -M Makefile.in -- $(DEPDIRS)
./config.status
Makefile.dep: deps
dep: Makefile.dep
#
#
# This build dependencies in *ALL* makefiles, and forces all
# dependencies to be inserted inline. For that reason, it should only
# be invoked manually or via "make dist". It should be run before
# creating release archives.
#
alldeps: perlreq tools/syncfiles.pl tools/mkdep.pl
alldeps: $(PERLREQ) tools/syncfiles.pl tools/mkdep.pl
$(RUNPERL) tools/syncfiles.pl Makefile.in Mkfiles/*.mak
$(RUNPERL) tools/mkdep.pl -i -M Makefile.in Mkfiles/*.mak -- \
$(DEPDIRS)
$(RM_F) Makefile.dep Mkfiles/*.dep
if [ $(EXTERNAL_DEPENDENCIES) -eq 1 ]; then \
./config.status --recheck; \
else \
./config.status; \
$(RM_F) *.dep
if [ -f config.status ]; then \
if [ $(EXTERNAL_DEPENDENCIES) -eq 1 ]; then \
./config.status --recheck; \
else \
./config.status; \
fi \
fi
# Strip internal dependency information from all Makefiles; this makes
# the output good for git checkin
cleandeps: perlreq tools/syncfiles.pl tools/mkdep.pl
cleandeps: $(PERLREQ) qtools/syncfiles.pl tools/mkdep.pl
$(RUNPERL) tools/syncfiles.pl Makefile.in Mkfiles/*.mak
$(RUNPERL) tools/mkdep.pl -e -M Makefile.in Mkfiles/*.mak -- \
$(DEPDIRS)
$(RM_F) Makefile.dep Mkfiles/*.dep
if [ $(EXTERNAL_DEPENDENCIES) -eq 0 ]; then \
./config.status --recheck; \
$(RM_F) *.dep
if [ -f config.status ]; then \
if [ $(EXTERNAL_DEPENDENCIES) -eq 0 ]; then \
./config.status --recheck; \
else \
./config.status; \
fi \
fi
#-- Magic hints to mkdep.pl --#
@ -493,5 +523,6 @@ cleandeps: perlreq tools/syncfiles.pl tools/mkdep.pl
# @path-separator: "/"
# @external: "Makefile.dep"
# @include-command: "-include"
# @selfrule: "1"
#-- Everything below is generated by mkdep.pl - do not edit --#
-include Makefile.dep

View File

@ -263,11 +263,19 @@ RDF2BINLINKS = rdoff\rdf2com$(X) rdoff\rdf2ith$(X) \
RDFLIB = rdoff\librdoff.$(A)
RDFLIBS = $(RDFLIB) $(NASMLIB)
# This rule is only used for rdoff, to allow common rules
MAKERDF = $(CC) $(ALL_CFLAGS) $(LDFLAGS) -o $@ $< $(RDFLIB) $(NASMLIB) $(LIBS)
rdoff\rdfdump$(X): rdoff\rdfdump.$(O) $(RDFLIBS)
$(MAKERDF)
rdoff\ldrdf$(X): rdoff\ldrdf.$(O) $(RDFLIBS)
$(MAKERDF)
rdoff\rdx$(X): rdoff\rdx.$(O) $(RDFLIBS)
$(MAKERDF)
rdoff\rdflib$(X): rdoff\rdflib.$(O) $(RDFLIBS)
$(MAKERDF)
rdoff\rdf2bin$(X): rdoff\rdf2bin.$(O) $(RDFLIBS)
$(MAKERDF)
rdoff\rdf2com$(X): rdoff\rdf2bin$(X)
$(RM_F) rdoff\rdf2com$(X)
cd rdoff && $(LN_S) rdf2bin$(X) rdf2com$(X)
@ -366,7 +374,5 @@ everything: all docs nsis
# @object-ending: ".$(O)"
# @path-separator: "\"
# @exclude: "config/config.h"
# @external: "msvc.dep"
# @include-command: "!INCLUDE"
#-- Everything below is generated by mkdep.pl - do not edit --#
!INCLUDE msvc.dep

View File

@ -34,6 +34,7 @@ HTMLAUX = nasmdoc.css local.css nasmlogw.png
SRCS = nasmdoc.src inslist.src changes.src version.src
OUT = html nasmdoc.txt nasmdoc.pdf
.SUFFIXES:
.SUFFIXES: .pfa .ph
all: $(OUT)

View File

@ -57,8 +57,8 @@ $barrier = "#-- Everything below is generated by mkdep.pl - do not edit --#\n";
sub scandeps($) {
my($file) = @_;
my $line;
my @xdeps = ();
my @mdeps = ();
my %xdeps;
my %mdeps;
open(my $fh, '<', $file)
or return; # If not openable, assume generated
@ -73,14 +73,14 @@ sub scandeps($) {
die "$0: cannot determine path for dependency: $file -> $nf\n";
}
$nf = $dep_path{$nf};
push(@mdeps, $nf);
push(@xdeps, $nf) unless ( defined($deps{$nf}) );
$mdeps{$nf}++;
$xdeps{$nf}++ unless ( defined($deps{$nf}) );
}
}
close($fh);
$deps{$file} = [@mdeps];
$deps{$file} = [keys(%mdeps)];
foreach my $xf ( @xdeps ) {
foreach my $xf ( keys(%xdeps) ) {
scandeps($xf);
}
}
@ -104,6 +104,7 @@ sub alldeps($$) {
# 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() ) {
@ -134,6 +135,8 @@ sub _insert_deps($$) {
my $sep = '/';
my $cont = "\\";
my $include_command = 'include';
my $selfrule = 0;
my $do_external = 0;
my $maxline = 78; # Seems like a reasonable default
my @exclude = (); # Don't exclude anything
my @genhdrs = ();
@ -167,12 +170,13 @@ sub _insert_deps($$) {
$include_command = $val;
} elsif ( $parm eq 'external' ) {
# Keep dependencies in an external file
if ( $force_inline ) {
next; # Don't output this line
} else {
$external = $val;
}
$external = $val;
} elsif ( $parm eq 'selfrule' ) {
$selfrule = !!$val;
}
} elsif ( $line =~ /^(\s*\#?\s*EXTERNAL_DEPENDENCIES\s*=\s*)([01])\s*$/ ) {
$is_external = $externalize ? 1 : $force_inline ? 0 : $2+0;
$line = $1.$is_external."\n";
} elsif ( $line eq $barrier ) {
$done = 1; # Stop reading input at barrier line
}
@ -181,20 +185,16 @@ sub _insert_deps($$) {
}
close($in);
if ( !defined($external) || $externalize ) {
# Write the existing Makefile content if we are producing
# inline content. If the Makefile has an
# EXTERNAL_DEPENDENCIES definition, update it to match.
map { s/\b(EXTERNAL_DEPENDENCIES\s*=\s*)[0-9]+\b/${1}${externalize}/; }
@outfile;
$is_external = $is_external && defined($external);
if ( !$is_external || $externalize ) {
print $out @outfile;
} else {
print $out $barrier; # Start generated file with barrier
}
if ( $externalize ) {
if ( defined($external) ) {
if ( $is_external ) {
print $out "$include_command $external\n";
}
return undef;
@ -206,19 +206,25 @@ sub _insert_deps($$) {
$do_exclude{$e} = 1;
}
my $dfile, $ofile, $str, $sl, $len;
my @deps, $dep;
foreach my $dfile ($external, sort(keys(%deps)) ) {
my $ofile;
my @deps;
foreach $dfile ( sort(keys(%deps)) ) {
if ( $dfile =~ /^(.*)\.[Cc]$/ ) {
$ofile = $1;
$str = convert_file($ofile, $sep).$obj.':';
$len = length($str);
print $out $str;
foreach $dep ($dfile, alldeps($dfile,1)) {
if ( $selfrule && $dfile eq $external ) {
$ofile = convert_file($dfile, $sep).':';
@deps = sort(keys(%deps));
} elsif ( $dfile =~ /^(.*)\.[Cc]$/ ) {
$ofile = convert_file($1, $sep).$obj.':';
@deps = ($dfile,alldeps($dfile,1));
}
if (defined($ofile)) {
my $len = length($ofile);
print $out $ofile;
foreach my $dep (@deps) {
unless ($do_exclude{$dep}) {
$str = convert_file($dep, $sep);
$sl = length($str)+1;
my $str = convert_file($dep, $sep);
my $sl = length($str)+1;
if ( $len+$sl > $maxline-2 ) {
print $out ' ', $cont, "\n ", $str;
$len = $sl;
@ -259,6 +265,7 @@ my @mkfiles = ();
my $mkmode = 0;
$force_inline = 0;
$externalize = 0;
$debug = 0;
while ( defined(my $arg = shift(@ARGV)) ) {
if ( $arg eq '-m' ) {
@ -268,6 +275,8 @@ while ( defined(my $arg = shift(@ARGV)) ) {
$force_inline = 1;
} elsif ( $arg eq '-e' ) {
$externalize = 1;
} elsif ( $arg eq '-d' ) {
$debug++;
} elsif ( $arg eq '-M' ) {
$mkmode = 1; # Futher filenames are output Makefile names
} elsif ( $arg eq '--' && $mkmode ) {
@ -294,7 +303,7 @@ foreach my $dir ( @files ) {
if ( $file =~ /\.[Cc]$/ ) {
push(@cfiles, $path);
} elsif ( $file =~ /\.[Hh]$/ ) {
print STDERR "Filesystem: $file -> $path\n";
print STDERR "Filesystem: $file -> $path\n" if ( $debug );
$dep_path{$file} = $path; # Allow the blank filename
$dep_path{$path} = $path; # Also allow the full pathname
}