Bug#1071246: libglib2.0-dev's python3 dependency alternative is posing challenges to cross building

Helmut Grohne helmut at subdivi.de
Fri Aug 2 11:10:48 BST 2024


Hi Simon and Niels,

(fixed Cc address for architecture-properties maintainers)

On Thu, Aug 01, 2024 at 05:26:04PM +0100, Simon McVittie wrote:
> On Thu, 01 Aug 2024 at 12:58:54 +0200, Helmut Grohne wrote:
> > I anticipate that more than gobject-introspection will need the
> > cross-exe-wrapper.
> 
> Yes, probably: Meson's "exe_wrapper" interface (which is where I got the
> idea from) is a generic thing that any cross-file describing a foreign
> architecture might have, and any upstream project that finds a need to
> do so can make use of it.
> 
> > Therefore, I'd prefer to decouple it.
> 
> I agree - I definitely wouldn't want gobject-introspection to be the
> place where this is maintained as a generic interface, because that's
> tied to a particular upstream project that is not really anything to do
> with how Debian supports cross architectures.
> 
> > Any ideas for a
> > good place for it? I am wondering whether architecture-properties would
> > be willing to carry this.
> 
> I think it should be in a native, "Debian-infrastructure-ish" source
> package: perhaps architecture-properties, build-essential or dpkg-cross
> (if dpkg-cross wasn't orphaned), or somewhere similar to those, or its
> own separate source package.

I talked to Niels off list and he was vaguely positive about riding on
architecture-properties. He had some concerns about the bus factor that
this work might impose on architecture-properties. Guillem also
indicated that he wants to give feedback though not right now.

To me this is sufficient to prototype an implementation. I'm attaching a
patch for architecture-properties that hopefully gets most of the
details right (thanks to Simon's design feedback). If you prefer
reviewing it on salsa, go
https://salsa.debian.org/debian/architecture-properties/-/merge_requests/1

I request that we give people at least one week to reply before
uploading this. I appreciate feedback from Niels as to how acceptable he
finds this contribution. I also appreciate feedback from Simon as to how
well this solves the gobject-introspection use case. Other reviews are
welcome as well.

Writing tests is a bit non-trivial. Whilst Ubuntu has pioneered an
autopkgtest extension for cross architecture testing, this does not seem
to be available in Debian. Testing the native case is rather boring in
my view. As for manual testing, I verified that :amd64 (natively), :i386
(without installing qemu), and :armhf (qemu) work as expected on amd64.

In the event that dpkg gains the Provides suggested by Simon, we can
delete both native-architecture and native-architecture-is.

Helmut
-------------- next part --------------
diff --minimal -Nru architecture-properties-0.1.1/Makefile architecture-properties-0.1.1+nmu1/Makefile
--- architecture-properties-0.1.1/Makefile	1970-01-01 01:00:00.000000000 +0100
+++ architecture-properties-0.1.1+nmu1/Makefile	2024-08-02 00:21:54.000000000 +0200
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+WRAPPER=$(DEB_HOST_GNU_TYPE)-cross-exe-wrapper
+all:$(WRAPPER) cross-exe-wrapper.1 cross-exe-test
+$(WRAPPER):cross-exe-wrapper.in
+	sed \
+		-e 's/#DEB_HOST_ARCH#/$(DEB_HOST_ARCH)/g' \
+		-e 's/#DEB_HOST_MULTIARCH#/$(DEB_HOST_MULTIARCH)/g' \
+		$< > $@
+	chmod +x $@
+cross-exe-wrapper.1:cross-exe-wrapper.in
+	pod2man --name cross-exe-wrapper $< > $@
+cross-exe-test:cross-exe-test.c
+	$(CC) $(CFLAGS) $(CPPFLAGS) -o $@ $<
+clean:
+	$(RM) -- *-cross-exe-wrapper cross-exe-wrapper.1 cross-exe-test
diff --minimal -Nru architecture-properties-0.1.1/cross-exe-test.c architecture-properties-0.1.1+nmu1/cross-exe-test.c
--- architecture-properties-0.1.1/cross-exe-test.c	1970-01-01 01:00:00.000000000 +0100
+++ architecture-properties-0.1.1+nmu1/cross-exe-test.c	2024-08-02 00:21:54.000000000 +0200
@@ -0,0 +1,40 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+void die(const char *message) __attribute__((noreturn))
+{
+	fprintf(stderr, "error: %s\n", message);
+	exit(2);
+}
+
+int main(void)
+{
+	char buff[1024];
+	char cmd[1024];
+	FILE *prog;
+	char *s;
+
+	/* Guess whether we are run in emulation by resolving /proc/self/exe
+	 * and matching its basename against our expected program name. We need
+	 * to fork another non-emulated process to avoid getting our readlink
+	 * syscall emulated too well and assume that coreutils' readlink is not
+	 * emulated.
+	 */
+	snprintf(cmd, sizeof(cmd), "readlink -n /proc/%d/exe", getpid());
+	prog = popen(cmd, "r");
+	if (!prog)
+		die("failed to spawn readlink");
+	if (!fgets(buff, sizeof(buff), prog))
+		die("failed to read output of readlink");
+	if (pclose(prog))
+		die("readlink failed");
+	s = strrchr(buff, '/');
+	if (s)
+		++s;
+	else
+		s = buff;
+	return !!strcmp(s, "cross-exe-test");
+}
diff --minimal -Nru architecture-properties-0.1.1/cross-exe-wrapper.in architecture-properties-0.1.1+nmu1/cross-exe-wrapper.in
--- architecture-properties-0.1.1/cross-exe-wrapper.in	1970-01-01 01:00:00.000000000 +0100
+++ architecture-properties-0.1.1+nmu1/cross-exe-wrapper.in	2024-08-02 00:21:54.000000000 +0200
@@ -0,0 +1,60 @@
+#!/bin/sh
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+: <<'POD2MAN'
+=head1 NAME
+
+<gnu-triplet>-cross-exe-wrapper - Run an executable using CPU emulation if needed
+
+=head1 SYNOPSIS
+
+<I<gnu-triplet>>B<-cross-exe-wrapper> <I<executable>> [I<options>]
+
+=head1 DESCRIPTION
+
+<I<gnu-triplet>>B<-cross-exe-wrapper> can be used to wrap a program compiled the architecture designated by its prefix in GNU triplet form.
+If the CPU happens to be able to run the program directly, it is run without emulation.
+The personality(2) of the execution environment is adjusted if necessary.
+The first argument must be a full path to the target executable.
+All further arguments are forwarded to the target executable.
+
+=head1 SEE ALSO
+
+L<qemu-user(1)>, L<qemu-user-static(1)>, L<personality(2)>
+
+=cut
+POD2MAN
+
+if test "$(dpkg --print-architecture)" = #DEB_HOST_ARCH#; then
+	exec "$@"
+fi
+
+cross_exe_test_output=$(/usr/lib/#DEB_HOST_MULTIARCH#/cross-exe-wrapper/cross-exe-test 2>&1)
+cross_exe_test_result=$?
+if test "$cross_exe_test_result" = 0; then
+	case #DEB_HOST_ARCH# in
+		amd64|x32)
+			exec setarch linux64 -- "$@"
+		;;
+		armel|armhf|i386|mipsel|powerpc|sparc)
+			exec setarch linux32 -- "$@"
+		;;
+	esac
+	exec "$@"
+fi
+
+if test "$cross_exe_test_result" = 2; then
+	echo "$cross_exe_test_output" >&2
+	exit 126
+fi
+
+if command -v qemu-#DEB_HOST_ARCH# >/dev/null; then
+	exec qemu-#DEB_HOST_ARCH# -- "$@"
+fi
+
+if command -v qemu-#DEB_HOST_ARCH#-static >/dev/null; then
+	exec qemu-#DEB_HOST_ARCH#-static -- "$@"
+fi
+
+echo "$0: failed to locate emulator for #DEB_HOST_ARCH#" >&2
+exit 126
diff --minimal -Nru architecture-properties-0.1.1/debian/changelog architecture-properties-0.1.1+nmu1/debian/changelog
--- architecture-properties-0.1.1/debian/changelog	2022-12-19 21:52:18.000000000 +0100
+++ architecture-properties-0.1.1+nmu1/debian/changelog	2024-08-02 00:21:54.000000000 +0200
@@ -1,3 +1,10 @@
+architecture-properties (0.1.1+nmu1) UNRELEASED; urgency=medium
+
+  * Non-maintainer upload.
+  * Add cross-exe-wrapper package and supporting packages.
+
+ -- Helmut Grohne <helmut at subdivi.de>  Fri, 02 Aug 2024 00:21:54 +0200
+
 architecture-properties (0.1.1) unstable; urgency=medium
 
   * Upload to unstable.
diff --minimal -Nru architecture-properties-0.1.1/debian/control architecture-properties-0.1.1+nmu1/debian/control
--- architecture-properties-0.1.1/debian/control	2022-12-14 14:57:33.000000000 +0100
+++ architecture-properties-0.1.1+nmu1/debian/control	2024-08-02 00:21:54.000000000 +0200
@@ -3,7 +3,7 @@
 Priority: optional
 Maintainer: Architecture Properties Maintainers <achitecture-properties at packages.debian.org>
 Uploaders: Niels Thykier <niels at thykier.net>,
-Build-Depends: debhelper-compat (= 13)
+Build-Depends: debhelper-compat (= 13), perl:any
 Rules-Requires-Root: no
 Standards-Version: 4.6.1
 Vcs-Git: https://salsa.debian.org/debian/architecture-properties.git
@@ -26,3 +26,51 @@
  in build-dependencies to simplify management of architecture
  support.
 
+Package: native-architecture
+Architecture: all
+Multi-Arch: no
+# Due to being M-A:no, this package can only ever satisfy native architecture
+# dependencies and that quite precisely is its purpose. Its Multi-Arch value
+# must not change even if the hinter says so.
+Description: Declarative native architecture constraint
+ This is a meta package that can only satisfy a dependency for the
+ native architecture. The native architecture is defined as the
+ architecture of the dpkg package by the Multi-Arch specification. By
+ depending on native-architecture, a client package can prevent its
+ installation for a non-native architecture.
+
+Package: native-architecture-is
+Architecture: any
+Multi-Arch: foreign
+Depends: native-architecture
+Provides: native-architecture-is-${DEB-HOST-ARCH}
+# Due to the dependency on native-architecture, this package can only ever be
+# installed for the native architecture. The native instance of this package
+# can always be installed. A dependency on native-architecture-is is thus
+# always satisfiable and thereby meaningless. The benefit of this package
+# arises from its Provides where the architecture constraint is lifted into the
+# package name.
+Description: Declarative native architecture assertions
+ This is a meta package that can be used to assert that a particular
+ architecture is native. The native architecture is defined as the
+ architecture of the dpkg package by the Multi-Arch specification. By
+ depending on e.g. native-architecture-is-amd64, a client package can
+ prevent its installation unless the native architecture is amd64.
+
+Package: cross-exe-wrapper
+Architecture: any
+Multi-Arch: same
+Depends:
+ ${shlibs:Depends},
+ native-architecture | native-architecture-is-amd64 [i386] | native-architecture-is-x32 [i386] | native-architecture-is-armhf [armel] | native-architecture-is-mips64el [mipsel] | native-architecture-is-ppc64 [powerpc] | native-architecture-is-sparc64 [sparc] | qemu-user | qemu-user-static,
+# The dependency ensures that either the architecture we use for installing is
+# the native architecture or the native architecture is sibling architecture of
+# the package architecture that is known to reliably run its code or a qemu is
+# installed. For instance, native-architecture-is-arm64 [armhf] is missing as
+# some recent arm64 CPUs no longer run 32bit code. The alternatives also ensure
+# that e.g. no qemu is required for installing cross-exe-wrapper:i386 on amd64
+# as we can reliably run i386 executables there without emulation.
+Description: Wrapper for executing binaries from other architectures
+ Provide a tool ${DEB_HOST_GNU_TYPE}-cross-exe-wrapper that can be
+ used to run ${DEB_HOST_ARCH} ELF executables on the current CPU
+ employing emulation technology if required.
diff --minimal -Nru architecture-properties-0.1.1/debian/copyright architecture-properties-0.1.1+nmu1/debian/copyright
--- architecture-properties-0.1.1/debian/copyright	2022-12-14 13:01:30.000000000 +0100
+++ architecture-properties-0.1.1+nmu1/debian/copyright	2024-08-02 00:21:54.000000000 +0200
@@ -1,7 +1,9 @@
 Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/
 
 Files: *
-Copyright: 2022 Niels Thykier <niels at thykier.net>
+Copyright:
+ 2022 Niels Thykier <niels at thykier.net>
+ 2024 Helmut Grohne <helmut at subdivi.de>
 License: GPL-2+
  The full text of the GPL version 2 is distributed in
  /usr/share/common-licenses/GPL-2 on Debian systems.
diff --minimal -Nru architecture-properties-0.1.1/debian/cross-exe-wrapper.install architecture-properties-0.1.1+nmu1/debian/cross-exe-wrapper.install
--- architecture-properties-0.1.1/debian/cross-exe-wrapper.install	1970-01-01 01:00:00.000000000 +0100
+++ architecture-properties-0.1.1+nmu1/debian/cross-exe-wrapper.install	2024-08-02 00:21:54.000000000 +0200
@@ -0,0 +1,2 @@
+${DEB_HOST_GNU_TYPE}-cross-exe-wrapper usr/bin
+cross-exe-test usr/lib/${DEB_HOST_MULTIARCH}/cross-exe-wrapper/
diff --minimal -Nru architecture-properties-0.1.1/debian/cross-exe-wrapper.links architecture-properties-0.1.1+nmu1/debian/cross-exe-wrapper.links
--- architecture-properties-0.1.1/debian/cross-exe-wrapper.links	1970-01-01 01:00:00.000000000 +0100
+++ architecture-properties-0.1.1+nmu1/debian/cross-exe-wrapper.links	2024-08-02 00:21:54.000000000 +0200
@@ -0,0 +1 @@
+usr/share/man/man1/cross-exe-wrapper.1.gz usr/share/man/man1/${DEB_HOST_GNU_TYPE}-cross-exe-wrapper.1.gz
diff --minimal -Nru architecture-properties-0.1.1/debian/cross-exe-wrapper.manpages architecture-properties-0.1.1+nmu1/debian/cross-exe-wrapper.manpages
--- architecture-properties-0.1.1/debian/cross-exe-wrapper.manpages	1970-01-01 01:00:00.000000000 +0100
+++ architecture-properties-0.1.1+nmu1/debian/cross-exe-wrapper.manpages	2024-08-02 00:21:54.000000000 +0200
@@ -0,0 +1 @@
+cross-exe-wrapper.1
diff --minimal -Nru architecture-properties-0.1.1/debian/rules architecture-properties-0.1.1+nmu1/debian/rules
--- architecture-properties-0.1.1/debian/rules	2022-12-14 13:03:02.000000000 +0100
+++ architecture-properties-0.1.1+nmu1/debian/rules	2024-08-02 00:21:54.000000000 +0200
@@ -1,9 +1,11 @@
 #!/usr/bin/make -f
 
+include /usr/share/dpkg/architecture.mk
+
 %:
 	dh $@
 
 execute_before_dh_gencontrol:
 	echo "DEB-HOST-ARCH-BITS=$(DEB_HOST_ARCH_BITS)" >> debian/architecture-properties.substvars
 	echo "DEB-HOST-ARCH-ENDIAN=$(DEB_HOST_ARCH_ENDIAN)" >> debian/architecture-properties.substvars
-
+	echo "DEB-HOST-ARCH=$(DEB_HOST_ARCH)" >> debian/native-architecture-is.substvars


More information about the pkg-gnome-maintainers mailing list