Current Path : /usr/bin/ |
Current File : //usr/bin/dpkg-checkbuilddeps |
#!/usr/bin/perl # # dpkg-checkbuilddeps # # Copyright © 2001 Joey Hess <joeyh@debian.org> # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see <http://www.gnu.org/licenses/>. use strict; use warnings; use Getopt::Long qw(:config posix_default bundling no_ignorecase); use Dpkg; use Dpkg::Gettext; use Dpkg::ErrorHandling; use Dpkg::Arch qw(get_host_arch); use Dpkg::Deps; use Dpkg::Control::Info; textdomain("dpkg-dev"); sub version() { printf(_g("Debian %s version %s.\n"), $progname, $version); exit(0); } sub usage { printf _g( "Usage: %s [<option>...] [<control-file>]") . "\n\n" . _g( "Options: -B binary-only, ignore -Indep. -d build-deps use given string as build dependencies instead of retrieving them from control file -c build-conf use given string for build conflicts instead of retrieving them from control file --admindir=<directory> change the administrative directory. -h, --help show this help message. --version show the version.") . "\n\n" . _g( "<control-file> is the control file to process (default: debian/control).") . "\n", $progname; } my $binary_only=0; my ($bd_value, $bc_value); if (!GetOptions('B' => \$binary_only, 'help|h' => sub { usage(); exit(0); }, 'version' => \&version, 'd=s' => \$bd_value, 'c=s' => \$bc_value, 'admindir=s' => \$admindir)) { usage(); exit(2); } my $controlfile = shift || "debian/control"; my $control = Dpkg::Control::Info->new($controlfile); my $fields = $control->get_source(); my $facts = parse_status("$admindir/status"); unless (defined($bd_value) or defined($bc_value)) { $bd_value = 'build-essential'; $bd_value .= ", " . $fields->{"Build-Depends"} if defined $fields->{"Build-Depends"}; if (not $binary_only and defined $fields->{"Build-Depends-Indep"}) { $bd_value .= ", " . $fields->{"Build-Depends-Indep"}; } $bc_value = $fields->{"Build-Conflicts"} if defined $fields->{"Build-Conflicts"}; if (not $binary_only and defined $fields->{"Build-Conflicts-Indep"}) { if ($bc_value) { $bc_value .= ", " . $fields->{"Build-Conflicts-Indep"}; } else { $bc_value = $fields->{"Build-Conflicts-Indep"}; } } } my (@unmet, @conflicts); if ($bd_value) { push @unmet, build_depends('Build-Depends/Build-Depends-Indep)', deps_parse($bd_value, reduce_arch => 1), $facts); } if ($bc_value) { push @conflicts, build_conflicts('Build-Conflicts/Build-Conflicts-Indep', deps_parse($bc_value, reduce_arch => 1, union => 1), $facts); } if (@unmet) { printf STDERR _g("%s: Unmet build dependencies: "), $progname; print STDERR join(" ", map { $_->output() } @unmet), "\n"; } if (@conflicts) { printf STDERR _g("%s: Build conflicts: "), $progname; print STDERR join(" ", map { $_->output() } @conflicts), "\n"; } exit 1 if @unmet || @conflicts; # Silly little status file parser that returns a Dpkg::Deps::KnownFacts sub parse_status { my $status = shift; my $facts = Dpkg::Deps::KnownFacts->new(); local $/ = ''; open(STATUS, "<$status") || die "$status: $!\n"; while (<STATUS>) { next unless /^Status: .*ok installed$/m; my ($package) = /^Package: (.*)$/m; my ($version) = /^Version: (.*)$/m; $facts->add_installed_package($package, $version); if (/^Provides: (.*)$/m) { my $provides = deps_parse($1, reduce_arch => 1, union => 1); next if not defined $provides; foreach (grep { $_->isa('Dpkg::Deps::Simple') } $provides->get_deps()) { $facts->add_provided_package($_->{package}, $_->{relation}, $_->{version}, $package); } } } close STATUS; return $facts; } # This function checks the build dependencies passed in as the first # parameter. If they are satisfied, returns false. If they are unsatisfied, # an list of the unsatisfied depends is returned. # # Additional parameters that must be passed: # * A reference to a hash of all "ok installed" the packages on the system, # with the hash key being the package name, and the value being the # installed version. # * A reference to a hash, where the keys are package names, and the # value is a true value iff some package installed on the system provides # that package (all installed packages provide themselves) # # Optionally, the architecture the package is to be built for can be passed # in as the 4th parameter. If not set, dpkg will be queried for the build # architecture. sub build_depends { return check_line(1, @_); } # This function is exactly like unmet_build_depends, except it # checks for build conflicts, and returns a list of the packages # that are installed and are conflicted with. sub build_conflicts { return check_line(0, @_); } # This function does all the work. The first parameter is 1 to check build # deps, and 0 to check build conflicts. sub check_line { my $build_depends=shift; my $fieldname=shift; my $dep_list=shift; my $facts=shift; my $host_arch = shift || get_host_arch(); chomp $host_arch; my @unmet=(); unless(defined($dep_list)) { error(_g("error occurred while parsing %s"), $fieldname); } if ($build_depends) { $dep_list->simplify_deps($facts); if ($dep_list->is_empty()) { return (); } else { return $dep_list->get_deps(); } } else { # Build-Conflicts my @conflicts = (); foreach my $dep ($dep_list->get_deps()) { if ($dep->get_evaluation($facts)) { push @conflicts, $dep; } } return @conflicts; } }