Package: dpkg
Version: 1.17.18
Severity: wishlist
Tags: patch

Hi,

this has not been agreed upon with a wider audience yet, so I'll post
this just as a proposal and to not loose the patch I attached.

By default, build dependencies are resolved using only host architecture
packages (except for dependencies on multiarch:foreign packages). The
multiarch cross spec [MACROSS] allows to explicitly select packages of
the build architecture instead, using the :native architecture
qualifier.

When building compilers, there is a third architecture to be considered
beyond build and host architecture: the target architecture which
specifies the architecture the compiler will produce code for.

Since it is already possible to explicitly depend on packages of the
host and build architecture, it only makes sense to also allow to
explicitly depend on packages of the target architecture. I propose the
:target qualifier for this purpose.

In the multiarch context, dependencies with the :target qualifier will
be resolved using packages of the target architecture except
multiarch:foreign packages which are not allowed to satisfy such a
dependency. This goes in line with the :native qualifier which also does
not allow multiarch:foreign packages. In this sense, the table on the
multiarch cross spec page would get a fourth column which would look
exactly like the third column except that s/native/target/.

In addition to preserving consistency between the input architectures
for a compilation (build, host and target) and the architectures that
one is allowed to select through build dependencies, having the :target
qualifier has a practical purpose.

When building gcc as a cross compiler, then it is currently necessary to
regenerate its debian/control to reflect its dependencies when building
a cross instead of a native compiler. If the :target qualifier would
exist, then it would be possible to switch between building a native
compiler or a cross compiler (or even a canadian cross?) without
regenerating debian/control.

Some build dependencies, like the one of gcc on binutils during stage2,
have to be translated to binutils-$TARGET:native. This can be done in
the same way that the translation of native compilers to cross compilers
is proposed using multiarch in section 4.1 of the bootstrap sprint
results [SPRINT] but is only possible once the :target qualifier exists.

Thank you for your consideration.

cheers, josch

[MACROSS] https://wiki.ubuntu.com/MultiarchCross
[SPRINT] https://lists.debian.org/debian-devel-announce/2014/08/msg00013.html
>From 8bf58f3dfa8f881646351bd3f2a406375396051b Mon Sep 17 00:00:00 2001
From: josch <[email protected]>
Date: Fri, 17 Oct 2014 08:39:30 +0200
Subject: [PATCH] =?UTF-8?q?scripts:=20Accept=20=E2=80=9C:target=E2=80=9D?=
 =?UTF-8?q?=20arch-qualified=20Build-Dependencies?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 debian/changelog               | 10 ++++++++--
 scripts/Dpkg/Arch.pm           | 19 +++++++++++++++++++
 scripts/Dpkg/Deps.pm           | 27 ++++++++++++++++++++++++---
 scripts/dpkg-checkbuilddeps.pl | 10 +++++++---
 4 files changed, 58 insertions(+), 8 deletions(-)

diff --git a/debian/changelog b/debian/changelog
index 6cd5db0..c17f9ef 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,4 +1,4 @@
-dpkg (1.17.19) UNRELEASED; urgency=low
+dpkg (1.17.19+nmu1) UNRELEASED; urgency=low
 
   [ Guillem Jover ]
   * Bump the Breaks on devscripts to 2.14.10 due to the new dpkg-architecture
@@ -17,7 +17,13 @@ dpkg (1.17.19) UNRELEASED; urgency=low
   [ Updated manpages translations ]
   * German (Helge Kreutzmann).
 
- -- Guillem Jover <[email protected]>  Sun, 12 Oct 2014 16:42:00 +0200
+  [ Johannes Schauer ]
+  * dpkg-checkbuilddeps:
+    - Add the --target-arch option to specify the target architecture for
+      building compilers
+    - Accept “:target” arch-qualified Build-Dependencies.
+
+ -- Johannes Schauer <[email protected]>  Fri, 17 Oct 2014 08:16:10 +0200
 
 dpkg (1.17.18) unstable; urgency=low
 
diff --git a/scripts/Dpkg/Arch.pm b/scripts/Dpkg/Arch.pm
index f561b66..e5bc67a 100644
--- a/scripts/Dpkg/Arch.pm
+++ b/scripts/Dpkg/Arch.pm
@@ -23,6 +23,7 @@ our $VERSION = '0.01';
 use Exporter qw(import);
 our @EXPORT_OK = qw(get_raw_build_arch get_raw_host_arch
                     get_build_arch get_host_arch get_gcc_host_gnu_type
+                    get_target_arch
                     get_valid_arches debarch_eq debarch_is debarch_is_wildcard
                     debarch_to_cpuattrs
                     debarch_to_gnutriplet gnutriplet_to_debarch
@@ -50,6 +51,7 @@ my %debarch_to_debtriplet;
     my $build_arch;
     my $host_arch;
     my $gcc_host_gnu_type;
+    my $target_arch;
 
     sub get_raw_build_arch()
     {
@@ -120,6 +122,23 @@ my %debarch_to_debtriplet;
     {
 	return Dpkg::BuildEnv::get('DEB_HOST_ARCH') || get_raw_host_arch();
     }
+
+    sub get_raw_target_arch()
+    {
+	return $target_arch if defined $target_arch;
+
+	if (!defined($target_arch)) {
+	    # Fall back to building a compiler for the host arch.
+	    $host_arch = get_raw_host_arch();
+	}
+
+	return $target_arch;
+    }
+
+    sub get_target_arch()
+    {
+	return Dpkg::BuildEnv::get('DEB_TARGET_ARCH') || get_raw_target_arch();
+    }
 }
 
 sub get_valid_arches()
diff --git a/scripts/Dpkg/Deps.pm b/scripts/Dpkg/Deps.pm
index 5e9728b..0aa186a 100644
--- a/scripts/Dpkg/Deps.pm
+++ b/scripts/Dpkg/Deps.pm
@@ -49,10 +49,10 @@ All the deps_* functions are exported by default.
 use strict;
 use warnings;
 
-our $VERSION = '1.05';
+our $VERSION = '1.06';
 
 use Dpkg::Version;
-use Dpkg::Arch qw(get_host_arch get_build_arch);
+use Dpkg::Arch qw(get_host_arch get_build_arch get_target_arch);
 use Dpkg::BuildProfiles qw(get_build_profiles);
 use Dpkg::ErrorHandling;
 use Dpkg::Gettext;
@@ -190,6 +190,11 @@ Dpkg::Arch::get_host_arch() to identify the proper architecture.
 Define the build architecture. By default it uses
 Dpkg::Arch::get_build_arch() to identify the proper architecture.
 
+=item target_arch (defaults to the current architecture)
+
+Define the target architecture. By default it uses
+Dpkg::Arch::get_target_arch() to identify the proper architecture.
+
 =item reduce_arch (defaults to 0)
 
 If set to 1, ignore dependencies that do not concern the current host
@@ -243,6 +248,7 @@ sub deps_parse {
     $options{reduce_arch} //= 0;
     $options{host_arch} //= get_host_arch();
     $options{build_arch} //= get_build_arch();
+    $options{target_arch} //= get_target_arch();
     $options{use_profiles} //= 1;
     $options{reduce_profiles} //= 0;
     $options{build_profiles} //= [ get_build_profiles() ];
@@ -267,6 +273,8 @@ sub deps_parse {
 	                                             $options{host_arch},
 	                                             build_arch =>
 	                                             $options{build_arch},
+	                                             target_arch =>
+	                                             $options{target_arch},
 	                                             build_dep =>
 	                                             $options{build_dep});
 	    if (not defined $dep_simple->{package}) {
@@ -558,6 +566,7 @@ sub new {
     $self->reset();
     $self->{host_arch} = $opts{host_arch} || Dpkg::Arch::get_host_arch();
     $self->{build_arch} = $opts{build_arch} || Dpkg::Arch::get_build_arch();
+    $self->{target_arch} = $opts{target_arch} || Dpkg::Arch::get_target_arch();
     $self->{build_dep} = $opts{build_dep} // 0;
     $self->parse_string($arg) if defined($arg);
     return $self;
@@ -609,6 +618,7 @@ sub parse_string {
             }x;
     if (defined($2)) {
 	return if $2 eq 'native' and not $self->{build_dep};
+	return if $2 eq 'target' and not $self->{build_dep};
 	$self->{archqual} = $2;
     }
     $self->{package} = $1;
@@ -724,11 +734,15 @@ sub _arch_qualifier_allows_implication {
     } elsif (defined $p and $p eq 'native') {
 	return 1 if defined $q and ($q eq 'any' or $q eq 'native');
 	return 0;
+    } elsif (defined $p and $p eq 'target') {
+	return 1 if defined $q and ($q eq 'any' or $q eq 'target');
+	return 0;
     } elsif (defined $p) {
 	return 1 if defined $q and ($p eq $q or $q eq 'any');
 	return 0;
     } else {
-	return 0 if defined $q and $q ne 'any' and $q ne 'native';
+	return 0 if defined $q and $q ne 'any' and $q ne 'native'
+			       and $q ne 'target';
 	return 1;
     }
 }
@@ -1419,6 +1433,7 @@ sub _find_package {
     return if not exists $self->{pkg}{$pkg};
     my $host_arch = $dep->{host_arch};
     my $build_arch = $dep->{build_arch};
+    my $target_arch = $dep->{target_arch};
     foreach my $p (@{$self->{pkg}{$pkg}}) {
 	my $a = $p->{architecture};
 	my $ma = $p->{multiarch};
@@ -1433,6 +1448,8 @@ sub _find_package {
 	    return $p if $ma eq 'allowed';
 	} elsif ($archqual eq 'native') {
 	    return $p if $a eq $build_arch and $ma ne 'foreign';
+	} elsif ($archqual eq 'target') {
+	    return $p if $a eq $target_arch and $ma ne 'foreign';
 	} else {
 	    return $p if $a eq $archqual;
 	}
@@ -1480,6 +1497,10 @@ sub _evaluate_simple_dep {
 
 =head1 CHANGES
 
+=head2 Version 1.06
+
+New option: Add target_arch option to Dpkg::Deps::deps_parse().
+
 =head2 Version 1.05
 
 New function: Dpkg::Deps::deps_iterate().
diff --git a/scripts/dpkg-checkbuilddeps.pl b/scripts/dpkg-checkbuilddeps.pl
index 3feba3a..47accc9 100755
--- a/scripts/dpkg-checkbuilddeps.pl
+++ b/scripts/dpkg-checkbuilddeps.pl
@@ -27,7 +27,7 @@ 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::Arch qw(get_host_arch get_target_arch);
 use Dpkg::BuildProfiles qw(get_build_profiles set_build_profiles);
 use Dpkg::Deps;
 use Dpkg::Control::Info;
@@ -52,6 +52,8 @@ sub usage {
   -c build-conf  use given string for build conflicts instead of
                  retrieving them from control file
   -a arch        assume given host architecture
+  --target-arch=<arch>
+                 assume given host architecture
   -P profiles    assume given build profiles (comma-separated list)
   --admindir=<directory>
                  change the administrative directory.
@@ -67,6 +69,7 @@ my $ignore_bd_indep = 0;
 my ($bd_value, $bc_value);
 my $bp_value;
 my $host_arch = get_host_arch();
+my $target_arch = get_target_arch();
 my $admindir = $Dpkg::ADMINDIR;
 my @options_spec = (
     'help|?' => sub { usage(); exit(0); },
@@ -76,6 +79,7 @@ my @options_spec = (
     'd=s' => \$bd_value,
     'c=s' => \$bc_value,
     'a=s' => \$host_arch,
+    'target-arch=s' => \$target_arch,
     'P=s' => \$bp_value,
     'admindir=s' => \$admindir,
 );
@@ -112,7 +116,7 @@ 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);
+                         host_arch => $host_arch, target_arch => $target_arch);
     error(_g('error occurred while parsing %s'),
           'Build-Depends/Build-Depends-Arch/Build-Depends-Indep')
         unless defined $dep;
@@ -121,7 +125,7 @@ if ($bd_value) {
 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);
+                         host_arch => $host_arch, target_arch => $target_arch);
     error(_g('error occurred while parsing %s'),
           'Build-Conflicts/Build-Conflicts-Arch/Build-Conflicts-Indep')
         unless defined $dep;
-- 
2.0.1

Reply via email to