2 # GPL copyright 2001 by Joey Hess <joeyh@debian.org>
9 Usage: dpkg-checkbuild [-B] [control-file]
10 -B binary-only, ignore -Indep
11 control-file control file to process [Default: debian/control]
15 my ($me)=$0=~m:.*/(.+):;
18 if (! GetOptions('-B' => \$binary_only)) {
22 my $control=shift || "debian/control";
24 open (CONTROL, $control) || die "$control: $!\n";
25 my @status=parse_status();
26 my (@unmet, @conflicts);
29 last if $_ eq ''; # end of first stanza
31 if (/^Build-Depends:\s+(.*)/i) {
32 push @unmet, build_depends($1, @status);
34 elsif (/^Build-Conflicts:\s+(.*)/i) {
35 push @conflicts, build_conflicts($1, @status);
37 elsif (! $binary_only && /^Build-Depends-Indep:\s+(.*)/i) {
38 push @unmet, build_depends($1, @status);
40 elsif (! $binary_only && /^Build-Conflicts-Indep:\s+(.*)/i) {
41 push @conflicts, build_conflicts($1, @status);
47 print STDERR "$me: Unmet build dependancies: ";
48 print STDERR join(", ", @unmet), "\n";
51 print STDERR "$me: Build conflicts: ";
52 print STDERR join(", ", @conflicts), "\n";
54 exit 1 if @unmet || @conflicts;
56 # This part could be replaced. Silly little status file parser.
57 # thanks to Matt Zimmerman. Returns two hash references that
58 # are exactly what the other functions need...
60 my $status=shift || "/var/lib/dpkg/status";
65 open(STATUS, "<$status") || die "$status: $!\n";
67 next unless /^Status: .*ok installed$/m;
69 my ($package) = /^Package: (.*)$/m;
70 push @{$providers{$package}}, $package;
71 ($version{$package}) = /^Version: (.*)$/m;
73 if (/^Provides: (.*)$/m) {
74 foreach (split(/,\s+/, $1)) {
75 push @{$providers{$_}}, $package;
81 return \%version, \%providers;
84 # This function checks the build dependancies passed in as the first
85 # parameter. If they are satisfied, returns false. If they are unsatisfied,
86 # an list of the unsatisfied depends is returned.
88 # Additional parameters that must be passed:
89 # * A reference to a hash of all "ok installed" the packages on the system,
90 # with the hash key being the package name, and the value being the
92 # * A reference to a hash, where the keys are package names, and the
93 # value is a true value iff some package installed on the system provides
94 # that package (all installed packages provide themselves)
96 # Optionally, the architecture the package is to be built for can be passed
97 # in as the 4th parameter. If not set, dpkg will be queried for the build
100 return check_line(1, @_);
103 # This function is exactly like unmet_build_depends, except it
104 # checks for build conflicts, and returns a list of the packages
105 # that are installed and are conflicted with.
106 sub build_conflicts {
107 return check_line(0, @_);
110 # This function does all the work. The first parameter is 1 to check build
111 # deps, and 0 to check build conflicts.
113 my $build_depends=shift;
115 my %version=%{shift()};
116 my %providers=%{shift()};
117 my $build_arch=shift || `dpkg --print-architecture`;
121 foreach my $dep (split(/,\s+/, $line)) {
124 ALTERNATE: foreach my $alternate (split(/\s*\|\s*/, $dep)) {
125 my ($package, $rest)=split(/\s+/, $alternate, 2);
127 # Check arch specifications.
128 if (defined $rest && $rest=~m/\[(.*?)\]/) {
131 foreach my $arch (split(' ', $arches)) {
132 if ($arch eq $build_arch) {
136 elsif ($arch eq "!$build_arch") {
139 elsif ($arch =~ /!/) {
140 # This is equivilant to
141 # having seen the current arch,
142 # unless the current arch
152 # This is a possibile way to meet the dependancy.
153 # Remove the arch stuff from $alternate.
154 $alternate=~s/\s+\[.*?\]//;
155 push @possibles, $alternate;
158 if (defined $rest && $rest=~m/\((..)\s+(.*?)\)/) {
162 if (! exists $version{$package}) {
163 # Not installed at all, so fail.
167 # Compare installed and needed
169 system("dpkg", "--compare-versions",
170 $version{$package}, $relation,
172 if (($? >> 8) != 0) {
177 elsif (! defined $providers{$package}) {
178 # It's not a versioned dependancy, and
179 # nothing provides it, so fail.
183 # If we get to here, the dependancy was met.
187 if (@possibles && (($build_depends && ! $ok) ||
188 (! $build_depends && $ok))) {
189 # TODO: this could return a more complex
190 # data structure instead to save re-parsing.
191 push @unmet, join (" | ", @possibles);