aboutsummaryrefslogtreecommitdiffstats
path: root/scripts/win-ldd.pl
blob: e3aa505de0376f0db7cfac46d808edcaa5881343 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
#!perl
use strict;
my %deploy;
my $objdump = $ENV{objdump} ? $ENV{objdump} : "objdump";
my @searchdirs;
my @systemdirs = (qr|^c:/windows|i, qr|^c:/winnt|i, qr|^/c/windows|i, qr|^/c/winnt|);

sub addDependenciesFor($) {
	open OBJDUMP, "-|", $objdump, "-p", $_[0] or die;
	while (<OBJDUMP>) {
		last if /^The Import Tables/;
	}
	while (<OBJDUMP>) {
		next unless /DLL Name: (.*)/;
		$deploy{$1} = 0 unless defined($deploy{$1});
		last if /^\w/;
	}
	close OBJDUMP;
}

sub findMissingDependencies {
	for my $name (keys %deploy) {
		next if $deploy{$name};
		my $path;
		for my $dir (@searchdirs) {
			my $fpath = "$dir/$name";
			my $lcfpath = "$dir/" . lc($name);
			if (-e $fpath) {
				$path = $fpath;
			} elsif (-e $lcfpath) {
				$path = $lcfpath;
			} else {
				next;
			}
			addDependenciesFor($path);
			last;
		}

		$path = "/missing/file" unless $path;
		$deploy{$name} = $path;
	}
}

for (@ARGV) {
	s/^-L//;
	next if /^-/;
	if (-d $_) {
		push @searchdirs, $_;
	} elsif (-f $_) {
		# Add $_'s path to the search list too
		my $dirname = $_;
		$dirname =~ s,/[^/]+$,,;
		unshift @searchdirs, $dirname;

		$deploy{$_} = $_;
		addDependenciesFor($_);
	}
}

# Append PATH to @searchdirs
@searchdirs = (@searchdirs, split(/:/, $ENV{PATH}));

# Remove system dirs from @searchdirs
@searchdirs = grep {
	my $sys = 0;
	for my $rx (@systemdirs) {
		if ($_ =~ $rx) {
			$sys = 1;
			last;
		}
	}
	!$sys;
} @searchdirs;

while (1) {
	findMissingDependencies();

	my $i = 0;
	while (my ($name, $path) = each(%deploy)) {
		next if $path;
		++$i;
		last;
	}
	last if $i == 0;
}

for (sort values %deploy) {
	next if $_ eq "/missing/file";
	print "$_\n";
}