summaryrefslogtreecommitdiff
path: root/util/mergedep.pl
blob: 1730d5392884b8efc293810e65a72ba369e38a62 (plain)
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
#!/usr/bin/perl
# Copyright 2003 Bryan Ford
# Distributed under the GNU General Public License.
#
# Usage: mergedep <main-depfile> [<new-depfiles> ...]
#
# This script merges the contents of all <new-depfiles> specified
# on the command line into the single file <main-depfile>,
# which may or may not previously exist.
# Dependencies in the <new-depfiles> will override
# any existing dependencies for the same targets in <main-depfile>.
# The <new-depfiles> are deleted after <main-depfile> is updated.
#
# The <new-depfiles> are typically generated by GCC with the -MD option,
# and the <main-depfile> is typically included from a Makefile,
# as shown here for GNU 'make':
#
#	.deps: $(wildcard *.d)
#		perl mergedep $@ $^
#	-include .deps
#
# This script properly handles multiple dependencies per <new-depfile>,
# including dependencies having no target,
# so it is compatible with GCC3's -MP option.
#

sub readdeps {
	my $filename = shift;

	open(DEPFILE, $filename) or return 0;
	while (<DEPFILE>) {
		if (/([^:]*):([^\\:]*)([\\]?)$/) {
			my $target = $1;
			my $deplines = $2;
			my $slash = $3;
			while ($slash ne '') {
				$_ = <DEPFILE>;
				defined($_) or die
					"Unterminated dependency in $filename";
				/(^[ \t][^\\]*)([\\]?)$/ or die
					"Bad continuation line in $filename";
				$deplines = "$deplines\\\n$1";
				$slash = $2;
			}
			#print "DEPENDENCY [[$target]]: [[$deplines]]\n";
			$dephash{$target} = $deplines;
		} elsif (/^[#]?[ \t]*$/) {
			# ignore blank lines and comments
		} else {
			die "Bad dependency line in $filename: $_";
		}
	}
	close DEPFILE;
	return 1;
}


if ($#ARGV < 0) {
	print "Usage: mergedep <main-depfile> [<new-depfiles> ..]\n";
	exit(1);
}

%dephash = ();

# Read the main dependency file
$maindeps = $ARGV[0];
readdeps($maindeps);

# Read and merge in the new dependency files
foreach $i (1 .. $#ARGV) {
	readdeps($ARGV[$i]) or die "Can't open $ARGV[$i]";
}

# Update the main dependency file
open(DEPFILE, ">$maindeps.tmp") or die "Can't open output file $maindeps.tmp";
foreach $target (keys %dephash) {
	print DEPFILE "$target:$dephash{$target}";
}
close DEPFILE;
rename("$maindeps.tmp", "$maindeps") or die "Can't overwrite $maindeps";

# Finally, delete the new dependency files
foreach $i (1 .. $#ARGV) {
	unlink($ARGV[$i]) or print "Error removing $ARGV[$i]\n";
}