Hi Tollef,
On Fri, Oct 24, 2014 at 02:27:16PM +0200, Tollef Fog Heen wrote:
> Have the links created by triggers on /usr/bin/$arch-gcc.
I have long pondered this possibility and concluded that triggers are
the wrong tool for the job. Here are a couple of reasons:
1. Triggering on /usr/bin/$arch-gcc is equivalent to triggering on
/usr/bin, because triggers cannot contain wildcards. Triggering on
/usr/bin is equivalent to triggering on every other package
installation. This sounds like a very bad idea.
2. So maybe triggering on something else is better. Possibly
/usr/lib/gcc? Unfortunately, cross compilers use /usr/lib/cross-gcc,
so we'd miss them. Furthermore, it has already been pointed out that
gcc is not the only compiler and pkg-config is used for other
languages than C. Packages such as pm-utils or x11-xkb-utils work
without one. So ideally, pkg-config should trigger on the
installation of any foreign-arch package.
3. During the freeze of jessie we have seen that when triggers are done
wrong (i.e. missing noawait when it is required) causes great pain.
Feel free to disagree, but in that case, please elaborate your
implementation plan or merge a patch that works.
So I talked to Guillem Jover and he came up with an entirely different
solution: dpkg hooks. By passing --pre-invoke or --post-invoke to dpkg,
it invokes a shell command before or after certain operations. Since
dpkg version 1.17.19, there are DPKG_HOOK_ACTION values
"add-architecture" and "remove-architecture" which trigger on dpkg
--add-architecture and dpkg --remove-architecture, i.e. exactly what we
need.
Of course, care must be taken to not break the system with a bad hook.
So I am attaching a patch that implements this very different solution
to the very same problem. It does away with splitting the pkg-config
package into two packages. Instead, it installs a new script to
/usr/share/pkg-config-dpkghook (which lives next to
pkg-config-crosswrapper, but you can certainly change the name). A
dpkg.cfg.d conffile configures the relevant hooks for dpkg. While the
hook is called for many dpkg operations, what is invoked is a shell that
carefully checks whether it is safe and useful to run
pkg-config-dpkghook.
I have extensively tested for whether the patch can cause breakage both
with automatic tools like piuparts and manually by various upgrade and
downgrade scenarios. Wookey has also experimented with this patch. It
went by a few more eyes for review.
So what do you think about this approach? Can you apply it? Please Cc me
in your reply.
Helmut
diff -u pkg-config-0.28/debian/changelog pkg-config-0.28/debian/changelog
--- pkg-config-0.28/debian/changelog
+++ pkg-config-0.28/debian/changelog
@@ -1,3 +1,11 @@
+pkg-config (0.28-1.1) UNRELEASED; urgency=medium
+
+ * Non-maintainer upload.
+ * Add symlinks to pkg-config-crosswrapper using dpkg hooks. (Closes:
+ #759556)
+
+ -- Helmut Grohne <[email protected]> Fri, 12 Jun 2015 23:02:08 +0200
+
pkg-config (0.28-1) unstable; urgency=medium
* New upstream release. (Closes: #699476, #744031)
diff -u pkg-config-0.28/debian/pkg-config.install
pkg-config-0.28/debian/pkg-config.install
--- pkg-config-0.28/debian/pkg-config.install
+++ pkg-config-0.28/debian/pkg-config.install
@@ -1,0 +2,2 @@
+debian/pkg-config-dpkghook usr/share
+debian/pkg-config-hook-config etc/dpkg/dpkg.cfg.d/
diff -u pkg-config-0.28/debian/rules pkg-config-0.28/debian/rules
--- pkg-config-0.28/debian/rules
+++ pkg-config-0.28/debian/rules
@@ -30,7 +30,7 @@
override_dh_auto_clean:
[ ! -f Makefile ] || $(MAKE) distclean DIST_SUBDIRS="check"
- chmod +x debian/pkg-config-crosswrapper
+ chmod +x debian/pkg-config-crosswrapper debian/pkg-config-dpkghook
override_dh_auto_test:
dh_auto_test -- TESTS_ENVIRONMENT=PKG_CONFIG=../pkg-config
LOG_COMPILER=/bin/bash
only in patch2:
unchanged:
--- pkg-config-0.28.orig/debian/pkg-config-dpkghook
+++ pkg-config-0.28/debian/pkg-config-dpkghook
@@ -0,0 +1,51 @@
+#!/usr/bin/perl
+#
+# Sets up /usr/bin/*-pkg-config symlinks to point to the cross wrapper.
+#
+# It is called from dpkg --post-invoke and from postinst with the "update"
+# argument to instate the necessary symlinks.
+#
+# It is called from prerm with the "remove" argument to remove all symlinks.
+#
+
+use strict;
+use warnings;
+
+use Dpkg::Arch qw(debarch_to_gnutriplet);
+use Dpkg::ErrorHandling qw(error);
+
+my $crosswrapper = "/usr/share/pkg-config-crosswrapper";
+
+my $action = $ARGV[0];
+error("parameter must be 'remove' or 'update'")
+ unless defined $action && ($action eq "remove" || $action eq "update");
+
+my $arch = `dpkg --print-architecture`;
+error('dpkg --print-architecture failed') if $? >> 8;
+my @architectures = `dpkg --print-foreign-architectures`;
+error('dpkg --print-foreign-architectures failed') if $? >> 8;
+push @architectures, $arch;
+chomp @architectures;
+
+my %gnutriplets = map { debarch_to_gnutriplet($_) => 1 } @architectures;
+
+my %symlinks = map { $_ => 1 } </usr/bin/*-pkg-config>;
+
+foreach my $symlink (keys %symlinks) {
+ $symlink =~ m,^/usr/bin/([^-]+-[^-]+-[^-]+)-pkg-config, or next;
+ next if exists $gnutriplets{$1} && $action eq "update";
+ next unless -l $symlink;
+ next unless readlink $symlink eq $crosswrapper;
+ unlink $symlink or
+ error("failed to remove symlink $symlink: $!");
+}
+
+if ($action eq 'update') {
+ foreach (keys %gnutriplets) {
+ my $linktarget = "/usr/bin/${_}-pkg-config";
+ next if exists $symlinks{$linktarget};
+ next if -e $linktarget;
+ symlink $crosswrapper, $linktarget or
+ error("failed to create symlink $linktarget to
$crosswrapper: $!");
+ }
+}
only in patch2:
unchanged:
--- pkg-config-0.28.orig/debian/pkg-config-hook-config
+++ pkg-config-0.28/debian/pkg-config-hook-config
@@ -0,0 +1 @@
+post-invoke=if test \( "$DPKG_HOOK_ACTION" = add-architecture -o
"$DPKG_HOOK_ACTION" = remove-architecture \) -a -x
/usr/share/pkg-config-dpkghook; then /usr/share/pkg-config-dpkghook update; fi
only in patch2:
unchanged:
--- pkg-config-0.28.orig/debian/pkg-config.postinst
+++ pkg-config-0.28/debian/pkg-config.postinst
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+#DEBHELPER#
+
+if test "$1" = configure; then
+ /usr/share/pkg-config-dpkghook update
+fi
only in patch2:
unchanged:
--- pkg-config-0.28.orig/debian/pkg-config.prerm
+++ pkg-config-0.28/debian/pkg-config.prerm
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+#DEBHELPER#
+
+if test "$1" = remove; then
+ /usr/share/pkg-config-dpkghook remove
+fi