Package: dpkg-cross
Version: 2.6.15-3
Tags: patch
User: helm...@debian.org
Usertags: rebootstrap

This is a complex issue. Please take some time to understand it.

When using dpkg-cross to convert a library package it simply copies the
shlibs file. A shlibs file for libc6 for example contains the line:

    libc 6 libc6 (>= 2.30)

The part after the second space is a dependency. When the original
package was e.g. libc6:mipsel, the converted package becomes
libc6-mipsel-cross:all. Now when dpkg-shlibdeps encounters a library
from libc6-mipsel-cross:all, it issues the relevant "libc6 (>= 2.30)"
dependency. However libc6-mipsel-cross:all is treated as a native
architecture (usually amd64). The inserted dependency lacks an
architecture qualifier.

The gcc-N packages need this architecture qualifier to convert them into
the usual -$arch-cross suffix. It has a cross_mangle_substvars to do
that:

    
https://salsa.debian.org/toolchain-team/gcc/-/blob/master/debian/rules.defs#L2203

When that suffix is missing, the issued dependency lacks the
-$arch-cross suffix. The cross-toolchain-base package takes care to
update shlibs files, see:

    
https://salsa.debian.org/toolchain-team/cross-toolchain-base/-/blob/master/debian/rules#L787

For doing that, cross-toolchain-base repacks the .deb twice. Once using
dpkg-cross and once using its repack target. It would make much more
sense to have this shlibs transformation inside dpkg-cross directly.

What does this mean in practise?

When you perform a toolchain bootstrap without cross-toolchain-base, you
end up without this shlibs fixup and when you build the gcc stage3 cross
compiler, you end up with support libraries with wrong dependencies:

    dpkg: dependency problems prevent configuration of 
lib64atomic1-mipsel-cross:
     lib64atomic1-mipsel-cross depends on libc6-mips64 (>= 2.30); however:
      Package libc6-mips64 is not installed.

    dpkg: error processing package lib64atomic1-mipsel-cross (--install):
     dependency problems - leaving unconfigured

After applying the attached patch, the generated dependencies in
multilib packages become correct. For non-multilib packages it also
happens to be wrong, but libatomic1-mipsel-cross simply depends on libc6
then. Doing so resolves to the native libc6 and dpkg is happy even when
libc6-mipsel-cross is missing.

The missing arch qualification is not a problem if you build "regular"
packages using dpkg-cross'ed packages. It only is a problem if you
attempt to produce dpkg-cross-style packages such as how gcc does it.
However, gcc nowadays is the main consumer of dpkg-cross'ed packages, so
we should make that experience painless.

So please consider applying the attached patch.

Helmut
diff --minimal -Nru dpkg-cross-2.6.15/debian/changelog 
dpkg-cross-2.6.15/debian/changelog
--- dpkg-cross-2.6.15/debian/changelog  2019-05-26 23:33:37.000000000 +0200
+++ dpkg-cross-2.6.15/debian/changelog  2020-04-03 15:33:57.000000000 +0200
@@ -1,3 +1,10 @@
+dpkg-cross (2.6.15-3.1) UNRELEASED; urgency=medium
+
+  * Non-maintainer upload.
+  * Arch qualify dependencies in shlibs files. (Closes: #-1)
+
+ -- Helmut Grohne <hel...@subdivi.de>  Fri, 03 Apr 2020 15:33:57 +0200
+
 dpkg-cross (2.6.15-3) unstable; urgency=medium
 
   [ Helmut Grohne ]
diff --minimal -Nru dpkg-cross-2.6.15/dpkg-cross dpkg-cross-2.6.15/dpkg-cross
--- dpkg-cross-2.6.15/dpkg-cross        2017-07-24 17:47:10.000000000 +0200
+++ dpkg-cross-2.6.15/dpkg-cross        2020-04-03 15:33:57.000000000 +0200
@@ -744,6 +744,35 @@
                close(TO);
                return 1;
        }
+       # Helper: fix shlibs file
+       # - arch-qualify dependencies
+       sub fix_shlibs($$) {
+               my ($from, $to) = @_;
+               ensure_dir($to) or return 0;
+               if (! open(FROM, $from)) {
+                       $msg = sprintf(_g("%s: failed to open %s: %s\n"), 
$progname, $from, $!);
+                       warn ($msg);
+                       return 0;
+               }
+               if (! open(TO, ">$to")) {
+                       $msg = sprintf(_g("%s: failed to open %s for writing: 
%s\n"), $progname, $to, $!);
+                       warn ($msg);
+                       close(FROM);
+                       return 0;
+               }
+               while (<FROM>) {
+                       if (m/^#/) {
+                               print TO;
+                       } elsif (m/((?:\S+:\s*)?\S+\s+\S+\s+)(.*)/) {
+                               print TO ($1 . join(",", map { s/\S+/$&:$arch/; 
$_; } split(/,/, $2)) . "\n");
+                       } else {
+                               print TO;
+                       }
+               }
+               close(FROM);
+               close(TO);
+               return 1;
+       }
        my $config = &get_config;
        $crosstype = `CC="" dpkg-architecture -f -a$arch -qDEB_HOST_GNU_TYPE 2> 
/dev/null`;
        chomp ($crosstype);
@@ -1089,7 +1118,7 @@
        # Link the shlibs file
        if (-f "$src/DEBIAN/shlibs") {
                print "Installing shlibs file\n" if $verbose >= 2;
-               link_file("$src/DEBIAN/shlibs", "$dst/DEBIAN/shlibs");
+               fix_shlibs("$src/DEBIAN/shlibs", "$dst/DEBIAN/shlibs");
        }
 
        # Create the control file.

Reply via email to