mkdep.pl: don't scan files until we know all the paths

Consistently identify dependencies by their path, not by their
basename.  This avoids missing indirect dependencies.  Furthermore, we
cannot start scanning files until we know the paths of all potential
targets.

Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
This commit is contained in:
H. Peter Anvin 2016-08-16 14:47:19 -07:00
parent 43e026277b
commit 3ffe8525e6

View file

@ -52,9 +52,9 @@ $barrier = "#-- Everything below is generated by mkdep.pl - do not edit --#\n";
#
sub scandeps($) {
my($file) = @_;
my($line, $nf);
my(@xdeps) = ();
my(@mdeps) = ();
my $line;
my @xdeps = ();
my @mdeps = ();
open(my $fh, '<', $file)
or return; # If not openable, assume generated
@ -64,7 +64,11 @@ sub scandeps($) {
$line =~ s:/\*.*\*/::g;
$line =~ s://.*$::;
if ( $line =~ /^\s*\#\s*include\s+\"(.*)\"\s*$/ ) {
$nf = $1;
my $nf = $1;
if (!defined($dep_path{$nf})) {
die "$0: cannot determine path for dependency: $file -> $nf\n";
}
$nf = $dep_path{$nf};
push(@mdeps, $nf);
push(@xdeps, $nf) unless ( defined($deps{$nf}) );
}
@ -72,21 +76,20 @@ sub scandeps($) {
close($fh);
$deps{$file} = [@mdeps];
foreach $file ( @xdeps ) {
scandeps($file);
foreach my $xf ( @xdeps ) {
scandeps($xf);
}
}
# %deps contains direct dependencies. This subroutine resolves
# indirect dependencies that result.
sub alldeps($) {
my($file) = @_;
my(%adeps);
my($dep,$idep);
sub alldeps($$) {
my($file, $level) = @_;
my %adeps;
foreach $dep ( @{$deps{$file}} ) {
foreach my $dep ( @{$deps{$file}} ) {
$adeps{$dep} = 1;
foreach $idep ( alldeps($dep) ) {
foreach my $idep ( alldeps($dep, $level+1) ) {
$adeps{$idep} = 1;
}
}
@ -97,7 +100,7 @@ sub alldeps($) {
# This almost certainly works only on relative filenames...
sub convert_file($$) {
my($file,$sep) = @_;
my(@fspec) = (basename($file));
my @fspec = (basename($file));
while ( ($file = dirname($file)) ne File::Spec->curdir() &&
$file ne File::Spec->rootdir() ) {
unshift(@fspec, basename($file));
@ -119,7 +122,7 @@ sub convert_file($$) {
sub insert_deps($) {
my($file) = @_;
$nexttemp++; # Unique serial number for each temp file
my($tmp) = File::Spec->catfile(dirname($file), 'tmp.'.$nexttemp);
my $tmp = File::Spec->catfile(dirname($file), 'tmp.'.$nexttemp);
open(my $in, '<', $file)
or die "$0: Cannot open input: $file\n";
@ -180,17 +183,9 @@ sub insert_deps($) {
$str = convert_file($ofile, $sep).$obj.':';
$len = length($str);
print $out $str;
foreach $dep ($dfile, alldeps($dfile)) {
foreach $dep ($dfile, alldeps($dfile,1)) {
unless ($do_exclude{$dep}) {
if (!defined($dep_path{$dep})) {
if ($dep eq $dfile) {
$dep_path{$dep} = $dfile;
print STDERR "Self: $dep -> $dfile\n";
} else {
die "$0: unknown dependency: $dep\n";
}
}
$str = convert_file($dep_path{$dep}, $sep);
$str = convert_file($dep, $sep);
$sl = length($str)+1;
if ( $len+$sl > $maxline-2 ) {
print $out ' ', $cont, "\n ", $str;
@ -238,6 +233,8 @@ while ( defined(my $arg = shift(@ARGV)) ) {
}
}
my @cfiles = ();
foreach my $dir ( @files ) {
opendir(DIR, $dir) or die "$0: Cannot open directory: $dir";
@ -245,7 +242,7 @@ foreach my $dir ( @files ) {
$path = ($dir eq File::Spec->curdir())
? $file : File::Spec->catfile($dir,$file);
if ( $file =~ /\.[Cc]$/ ) {
scandeps($path);
push(@cfiles, $path);
} elsif ( $file =~ /\.[Hh]$/ ) {
print STDERR "Filesystem: $file -> $path\n";
$dep_path{$file} = $path;
@ -254,6 +251,10 @@ foreach my $dir ( @files ) {
closedir(DIR);
}
foreach $mkfile ( @mkfiles ) {
foreach my $cfile ( @cfiles ) {
scandeps($cfile);
}
foreach my $mkfile ( @mkfiles ) {
insert_deps($mkfile);
}