#!/usr/bin/perl # update-multiarch.pl -- adapt to incremental multiarch support # Copyright (C) 2009 Neil Williams # # This package 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 3 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 . use strict; use warnings; use File::Basename; use Debian::DpkgCross; use Parse::DebControl; use Parse::Debian::Packages; use vars qw/ $file $fh $progname %package $APTCROSSVERSION @malist /; $progname = &basename($0); $APTCROSSVERSION = &get_cache_apt_version; while( @ARGV ) { $_= shift( @ARGV ); last if m/^--$/; if (!/^-/) { unshift(@ARGV,$_); last; } elsif (/^(-\?|-h|--help)$/) { &showusage; &showhelp; exit( 0 ); } elsif (/^(-f|--file)$/) { $file = shift; } } die ("$progname: Need to specify a Packages file to check.") if (not defined $file); my %etc_hash = (); # the list derived from the /etc/ file my %additional = (); # the list derived from the Packages file # first, reset the current list my $out = "/var/lib/apt-cross/multiarch.list"; if (-f $out and -w $out) { open (OUT, ">$out"); print OUT "# this file is empty initially and updated using\n"; print OUT "# /usr/share/apt-cross/update-multiarch.pl\n\n"; close (OUT); chmod (0666, $out); } #/etc/dpkg-cross/multiarch-cross.d/ my $m = &read_multiarch_list; @malist = @$m if (defined $m); foreach my $mline (@malist) { $etc_hash{$mline}++; } $fh = IO::File->new("$file") or die "$!\n"; my $parser = Parse::Debian::Packages->new( $fh ); while (%package = $parser->next) { $additional{$package{'Package'}}++ if ((defined $package{'Multi-Arch'}) and (not exists $etc_hash{$package{'Package'}})); } # write $additional to /var/lib/apt-cross/multiarch.list if (-f $out and -w $out) { open (OUT, ">$out"); print OUT "# this file is empty initially and updated using\n"; print OUT "# /usr/share/apt-cross/update-multiarch.pl\n\n"; foreach my $l (sort keys %additional) { print OUT "$l\n"; } close (OUT); chmod (0666, $out); } exit 0; sub showusage { print(STDERR </dev/null`; return $dpkg if ($dpkg !~ /^\s*$/); return $fallback; } =pod =head1 Name update-multiarch.pl - Multiarch helper for dpkg-cross and related tools =head1 Description Identifies the binary package names from the specified Packages file and compare the identified list against the lists in F then write out the list of additional package names to F. The list is overwritten each time F is run. This config file helper is tied absolutely to a single target suite - use a chroot for a different target suite. =head2 Example of how dpkg-cross handles the list If libfoo1 depends on libbar0 and libbar0 has transitioned to Multi-Arch compliance (and is listed in either F or F, then libfoo1-ARCH-cross will have a versioned depends on libbar0 to ensure that the multiarch version is installed. Depends: libc6-armel-cross (>= 2.4), libbar0 (>= 0.0.2-1), libbaz2-armel-cross Provides: libfoo1-armel-dcv1 Once libfoo has transitioned and the list updated using this helper or some alternative method, a rebuilt libfoo-ARCH-cross will be empty, and contain a new control field: x-Multiarch: delete along with a mangled package description that tells users to delete all these packages as soon as practical. (emprunecross can be used here.) Depends: libc6-armel-cross (>= 2.4), libbar0 (>= 0.0.2-1), libbaz2-armel-cross Provides: libfoo1-armel-dcv1 X-Multiarch: delete =head1 Alternatives A simple list of packages can be found using C: grep-aptavail -s Package -F Multi-Arch same grep-aptavail -s Package -F Multi-Arch foreign grep-aptavail -s Package -F Multi-Arch allowed However, note that grep-aptavail uses all sources in your apt configuration and the results will not necessarily match either the list for the target suite or for the target architecture. =head1 Multi-arch field meanings for dpkg-cross: Multi-Arch: same This package is co-installable with itself, but it must not be used to satisfy the dependency of any package of a different architecture from itself. dpkg-cross needs to include this dependency as a native dependency, so that the package for the cross architecture can be installed. Multi-Arch: foreign The package is not co-installable with itself, but should be allowed to satisfy the dependencies of a package of a different arch from itself. dpkg-cross needs to include this dependency as a native dependency, so that the package is deemed to already meet the cross dependency. Multi-Arch: allowed This permits the reverse-dependencies of the package to annotate their Depends: field to indicate that a foreign architecture version of the package satisfies the dependencies, but does not change the resolution of any existing dependencies. This value exists to prevent any packages from incorrectly annotating dependencies as being architecture-neutral without coordination with the maintainer of the depended-on package. dpkg-cross needs to include this dependency as a native dependency, so that the package is deemed to already meet the cross dependency. See: https://wiki.ubuntu.com/MultiarchSpec =cut