Package: dpkg-dev
Version: 1.21.9
Severity: wishlist

Hello,

thank you for maintaining dpkg!

I often find myself[1] in need of a tool that, given a source package,
prints a list of its build depends, given an architecture, a build
profile, and so on.

dpkg-checkbuilddeps does internally generate it, and then only print the
list of packages not currently installed.

Would it be possible to add a way to print the unfiltered list?

I've made something that does it by chopping away the filtering bits
from dpkg-checkbuilddeps (see attachment).

Ideally, it can become a --print-depends/--print-conflicts option to
dpkg-checkbuilddeps, instead of a separate tool. Unfortunately my
perl-foo is too rusty to pretend I could propose a competent patch :/


Enrico

[1] and I'm apparently in good company, considering how many times this
    is reimplemented in various places in Debian

-- Package-specific info:
This system uses merged-usr-via-aliased-dirs, going behind dpkg's
back, breaking its core assumptions. This can cause silent file
overwrites and disappearances, and its general tools misbehavior.
See <https://wiki.debian.org/Teams/Dpkg/FAQ#broken-usrmerge>.

-- System Information:
Debian Release: bookworm/sid
  APT prefers testing
  APT policy: (500, 'testing')
Architecture: amd64 (x86_64)

Kernel: Linux 6.0.0-2-amd64 (SMP w/4 CPU threads; PREEMPT)
Locale: LANG=en_IE.UTF-8, LC_CTYPE=en_IE.UTF-8 (charmap=UTF-8), 
LANGUAGE=en_IE:en
Shell: /bin/sh linked to /usr/bin/dash
Init: systemd (via /run/systemd/system)
LSM: AppArmor: enabled

Versions of packages dpkg-dev depends on:
ii  binutils      2.39-8
ii  bzip2         1.0.8-5+b1
ii  libdpkg-perl  1.21.9
ii  make          4.3-4.1
ii  patch         2.7.6-7
ii  perl          5.36.0-4
ii  tar           1.34+dfsg-1
ii  xz-utils      5.2.7-0.1

Versions of packages dpkg-dev recommends:
ii  build-essential          12.9
ii  clang-14 [c-compiler]    1:14.0.6-2
ii  fakeroot                 1.29-1
ii  gcc [c-compiler]         4:12.2.0-1
ii  gcc-10 [c-compiler]      10.4.0-5
ii  gcc-12 [c-compiler]      12.2.0-9
ii  gnupg                    2.2.40-1
ii  gpgv                     2.2.40-1
ii  libalgorithm-merge-perl  0.08-5

Versions of packages dpkg-dev suggests:
ii  debian-keyring  2022.08.11

-- no debconf information
#!/usr/bin/perl
#
# dpkg-checkbuilddeps
#
# Copyright © 2001 Joey Hess <jo...@debian.org>
# Copyright © 2006-2009, 2011-2015 Guillem Jover <guil...@debian.org>
# Copyright © 2007-2011 Raphael Hertzog <hert...@debian.org>
# Copyright © 2022 Enrico Zini <enr...@enricozini.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 <https://www.gnu.org/licenses/>.

use strict;
use warnings;

use Getopt::Long qw(:config posix_default bundling_values no_ignorecase);

use Dpkg ();
use Dpkg::Gettext;
use Dpkg::ErrorHandling;
use Dpkg::Arch qw(get_host_arch);
use Dpkg::Vendor qw(run_vendor_hook);
use Dpkg::BuildProfiles qw(get_build_profiles set_build_profiles);
use Dpkg::Deps;
use Dpkg::Control::Info;

textdomain('dpkg-dev');

sub version()
{
    printf g_("Debian %s version %s.\n"), $Dpkg::PROGNAME, $Dpkg::PROGVERSION;
}

sub usage {
    printf g_(
'Usage: %s [<option>...] [<control-file>]')
    . "\n\n" . g_(
'Options:
  -A             ignore Build-Depends-Arch and Build-Conflicts-Arch.
  -B             ignore Build-Depends-Indep and Build-Conflicts-Indep.
  -I             ignore built-in build dependencies and conflicts.
  -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
  -a arch        assume given host architecture
  -P profiles    assume given build profiles (comma-separated list)
  --admindir=<directory>
                 change the administrative directory.
  -?, --help     show this help message.
      --version  show the version.')
    . "\n\n" . g_(
'<control-file> is the control file to process (default: debian/control).')
        . "\n", $Dpkg::PROGNAME;
}

my $ignore_bd_arch = 0;
my $ignore_bd_indep = 0;
my $ignore_bd_builtin = 0;
my ($bd_value, $bc_value);
my $bp_value;
my $host_arch = get_host_arch();
my $admindir = $Dpkg::ADMINDIR;
my @options_spec = (
    'help|?' => sub { usage(); exit(0); },
    'version' => sub { version(); exit 0; },
    'A' => \$ignore_bd_arch,
    'B' => \$ignore_bd_indep,
    'I' => \$ignore_bd_builtin,
    'd=s' => \$bd_value,
    'c=s' => \$bc_value,
    'a=s' => \$host_arch,
    'P=s' => \$bp_value,
    'admindir=s' => \$admindir,
);

{
    local $SIG{__WARN__} = sub { usageerr($_[0]) };
    GetOptions(@options_spec);
}

# Update currently active build profiles.
set_build_profiles(split(/,/, $bp_value)) if ($bp_value);
my @build_profiles = get_build_profiles();

my $controlfile = shift // 'debian/control';

my $control = Dpkg::Control::Info->new($controlfile);
my $fields = $control->get_source();

unless (defined($bd_value) or defined($bc_value)) {
    my @bd_list;
    push @bd_list, run_vendor_hook('builtin-build-depends')
        if not $ignore_bd_builtin;
    push @bd_list, $fields->{'Build-Depends'};
    push @bd_list, $fields->{'Build-Depends-Arch'} if not $ignore_bd_arch;
    push @bd_list, $fields->{'Build-Depends-Indep'} if not $ignore_bd_indep;
    $bd_value = deps_concat(@bd_list);

    my @bc_list;
    push @bc_list, run_vendor_hook('builtin-build-conflicts')
        if not $ignore_bd_builtin;
    push @bc_list, $fields->{'Build-Conflicts'};
    push @bc_list, $fields->{'Build-Conflicts-Arch'} if not $ignore_bd_arch;
    push @bc_list, $fields->{'Build-Conflicts-Indep'} if not $ignore_bd_indep;
    $bc_value = deps_concat(@bc_list);
}
my (@unmet, @conflicts);

if ($bd_value) {
    my $dep = deps_parse($bd_value, reduce_restrictions => 1,
                         build_dep => 1, build_profiles => \@build_profiles,
                         host_arch => $host_arch);
    error(g_('cannot parse %s field'),
          'Build-Depends/Build-Depends-Arch/Build-Depends-Indep')
        unless defined $dep;
    push @unmet, $dep->get_deps();
}
if ($bc_value) {
    my $dep = deps_parse($bc_value, reduce_restrictions => 1, union => 1,
                         build_dep => 1, build_profiles => \@build_profiles,
                         host_arch => $host_arch);
    error(g_('cannot parse %s field'),
          'Build-Conflicts/Build-Conflicts-Arch/Build-Conflicts-Indep')
        unless defined $dep;
    push @conflicts, $dep->get_deps();
}

for my $pkg (@unmet)
{
        print "DEP: $pkg\n";
}
for my $pkg (@conflicts)
{
        print "DEP: $pkg\n";
}

Reply via email to