[PATCH 7/7] Fix experimental multiarch support.
---
examples/multiarch.conf | 31 ++++----
multistrap | 187 +++++++++++++++++++++++------------------------
pod/multistrap | 59 ++++++++++-----
3 filer ändrade, 146 tillägg(+), 131 borttagningar(-)
diff --git a/examples/multiarch.conf b/examples/multiarch.conf
index dfa7fd50..a058a334 100644
--- a/examples/multiarch.conf
+++ b/examples/multiarch.conf
@@ -1,4 +1,4 @@
-# Example multistrap configuration file for the sid shortcut.
+# Example a multistrap configuration file for a multiarch chroot.
[General]
arch=
@@ -15,29 +15,26 @@ explicitsuite=false
# extract all downloaded archives (default is true)
unpack=true
# enable MultiArch for the specified architectures
-multiarch=armel mipsel
+multiarch=amd64 i386 x32
# the order of sections is not important.
# the bootstrap option determines which repository
# is used to calculate the list of Priority: required packages.
-bootstrap=Debian Foreign Test
-aptsources=Debian
+bootstrap=Debian DebianPorts
+aptsources=Debian DebianPorts
[Debian]
+suite=sid
+multiarch=amd64 i386
packages=apt
+packages=libc6:amd64 libgcc1:amd64
+packages=libc6:i386 libgcc1:i386
source=http://cdn.debian.net/debian
keyring=debian-archive-keyring
-suite=wheezy
-
-[Foreign]
-packages=libgcc1
-packages=libc6
-architecture=armel
-source=http://cdn.debian.net/debian
-keyring=debian-archive-keyring
-suite=wheezy
-[Test]
-packages=
-source=http://ftp.uk.debian.org/emdebian-multiarch/
-keyring=
+[DebianPorts]
suite=sid
+arch=x32
+packages=libc6 libgcc1
+source=http://ftp.debian-ports.org/debian
+keyring=debian-ports-archive-keyring
+omitdebsrc=true
diff --git a/multistrap b/multistrap
index 6f81fd56..6c812235 100755
--- a/multistrap
+++ b/multistrap
@@ -36,7 +36,7 @@ use vars qw/ $progname $ourversion $dstrap $extra @aptsources
$explicit_suite $allow_recommends %omitdebsrc @dsclist @sectoutput
%flatfile %important $addimportant @debconf $hookdir %hooks
$warn_count $use_shortcut @foreignarches $olddpkg $ignorenative
- %foreignpkgs $markauto $default_release /;
+ %arches %multiarches $markauto $default_release /;
setlocale(LC_MESSAGES, "");
textdomain("multistrap");
@@ -45,7 +45,6 @@ $ourversion = &our_version();
$default_release = "*";
$unpack = "true";
%omitdebsrc=();
-%foreignpkgs=();
while( @ARGV ) {
$_= shift( @ARGV );
last if m/^--$/;
@@ -200,23 +199,24 @@ if (not -d "${dir}etc/network") {
if (not -d "${dir}dev") {
mkdir_fatal ("${dir}dev");
}
-if (($olddpkg == 0) and (scalar (@foreignarches) > 0)) {
+if (scalar (@foreignarches) > 0) {
+ # Support old unoffical version
if (not -d "${dir}etc/dpkg/dpkg.cfg.d/") {
system_fatal ("mkdir -p ${dir}etc/dpkg/dpkg.cfg.d/");
}
- if (not -f "${dir}etc/dpkg/dpkg.cfg.d/multiarch") {
- open (MA, ">${dir}etc/dpkg/dpkg.cfg.d/multiarch");
- foreach my $farch (@foreignarches) {
- print MA "foreign-architecture $farch\n";
- }
- close (MA);
- open (VMA, ">${dir}${dpkgdir}arch");
- print VMA "$host\n";
- foreach my $farch (@foreignarches) {
- print VMA "$farch\n";
- }
- close (VMA);
+ open (MA, ">${dir}etc/dpkg/dpkg.cfg.d/multiarch");
+ foreach my $farch (@foreignarches) {
+ print MA "foreign-architecture $farch\n";
+ }
+ close (MA);
+
+ # Support new offical version
+ open (VMA, ">${dir}${dpkgdir}arch");
+ print VMA "$arch\n";
+ foreach my $farch (@foreignarches) {
+ print VMA "$farch\n";
}
+ close (VMA);
}
&guard_lib64($dir);
@@ -253,20 +253,12 @@ foreach my $aptsrc (@debootstrap) {
or die _g("Cannot open sources list"). $!;
my $mirror = $sources{$aptsrc};
my $suite = (exists $flatfile{$aptsrc}) ? "" : $suites{$aptsrc};
- my $component = (exists $flatfile{$aptsrc}) ? ""
- : (defined $components{$aptsrc}) ? $components{$aptsrc} : "main";
+ my $component = (exists $flatfile{$aptsrc}) ? "" : $components{$aptsrc};
+ my @arches=();
+ push @arches, $arches{$aptsrc};
+ push @arches, split(/ /, $multiarches{$aptsrc});
if (defined $mirror and defined $suite) {
- if ($olddpkg != 0) {
- print SOURCES "deb $mirror $suite $component\n";
- } else {
- if (scalar (@foreignarches) == 0) {
- print SOURCES "deb [arch=$arch] $mirror $suite $component\n";
- } else {
- foreach my $farch (@foreignarches) {
- print SOURCES "deb [arch=$farch] $mirror $suite $component\n";
- }
- }
- }
+ print SOURCES "deb [arch=" . join(",", @arches) . "] $mirror $suite $component\n";
print SOURCES "deb-src $mirror $suite $component\n" if (not defined $omitdebsrc{$aptsrc});
close SOURCES;
}
@@ -331,26 +323,23 @@ if ((defined $k) and (not defined $noauth)) {
}
$config_str = '';
$config_str .= " -o Apt::Architecture=$arch";
-$config_str .= " -o Dir::Etc::TrustedParts=${dir}${etcdir}trusted.gpg.d";
-$config_str .= " -o Dir::Etc::Trusted=${dir}${etcdir}trusted.gpg.d/trusted.gpg";
+$config_str .= " -o Dir=$dir";
+$config_str .= " -o Dir::Etc=${dir}${etcdir}";
+$config_str .= " -o Dir::State=${dir}${libdir}";
+$config_str .= " -o Dir::State::Status=${dir}${dpkgdir}status";
+$config_str .= " -o Dir::Cache=${dir}${cachedir}";
+$config_str .= " -o DPkg::options::=--root=${dir}";
$config_str .= " -o Apt::Get::AllowUnauthenticated=true"
if (defined $noauth);
$config_str .= " -o Apt::Get::Download-Only=true";
$config_str .= " -o Apt::Install-Recommends=false"
if (not defined $allow_recommends);
-$config_str .= " -o Dir=$dir";
-$config_str .= " -o Dir::Etc=${dir}${etcdir}";
-$config_str .= " -o Dir::Etc::Parts=${dir}${etcdir}apt.conf.d/";
-$config_str .= " -o Dir::Etc::PreferencesParts=${dir}${etcdir}preferences.d/";
$config_str .= " -o APT::Default-Release=$default_release";
# if (not defined $preffile);
if (defined $deflist) {
$sourcesname = "sources.list.d/multistrap.sources.list";
$config_str .= " -o Dir::Etc::SourceList=${dir}${etcdir}$sourcesname";
}
-$config_str .= " -o Dir::State=${dir}${libdir}";
-$config_str .= " -o Dir::State::Status=${dir}${dpkgdir}status";
-$config_str .= " -o Dir::Cache=${dir}${cachedir}";
printf (_g("Getting package lists: apt-get %s update\n"), $config_str);
$retval = system ("apt-get $config_str update");
$retval >>= 8;
@@ -450,20 +439,12 @@ foreach my $aptsrc (@aptsources) {
or die _g("Cannot open sources list"). $!;
my $mirror = $sources{$aptsrc};
my $suite = (exists $flatfile{$aptsrc}) ? "" : $suites{$aptsrc};
- my $component = (exists $flatfile{$aptsrc}) ? ""
- : (defined $components{$aptsrc}) ? $components{$aptsrc} : "main";
+ my $component = (exists $flatfile{$aptsrc}) ? "" : $components{$aptsrc};
+ my @arches=();
+ push @arches, $arches{$aptsrc};
+ push @arches, split(/ /, $multiarches{$aptsrc});
if (defined $mirror and defined $suite) {
- if ($olddpkg != 0) {
- print SOURCES "deb $mirror $suite $component\n";
- } else {
- if (scalar (@foreignarches) == 0) {
- print SOURCES "deb [arch=$arch] $mirror $suite $component\n";
- } else {
- foreach my $farch (@foreignarches) {
- print SOURCES "deb [arch=$farch] $mirror $suite $component\n";
- }
- }
- }
+ print SOURCES "deb [arch=" . join(",", @arches) . "] $mirror $suite $component\n";
print SOURCES "deb-src $mirror $suite $component\n" if (not defined $omitdebsrc{$aptsrc});
close SOURCES;
}
@@ -1142,8 +1123,8 @@ sub cascade {
$value = $key if (ref $key eq "HASH");
$keys{$type} = $value;
}
- foreach $section (sort keys %keys) {
- if ($section eq "general") {
+ my $section = "general";
+ {
$arch = $keys{$section}{'arch'}
if (defined $keys{$section}{'arch'} and (not defined $arch));
$dir = $keys{$section}{'directory'}
@@ -1212,10 +1193,8 @@ sub cascade {
}
}
my @ma=();
- if ($olddpkg == 0) {
- @ma = split(' ',lc($keys{$section}{'multiarch'}))
- if (defined $keys{$section}{'multiarch'});
- }
+ @ma = split(' ',lc($keys{$section}{'multiarch'}))
+ if (defined $keys{$section}{'multiarch'});
push @foreignarches, @ma;
my @d=();
@d = split(' ', lc($keys{$section}{'debootstrap'}))
@@ -1244,54 +1223,74 @@ sub cascade {
}
}
push @includes, @i;
- } else {
+ if ($olddpkg != 0 && (scalar (@foreignarches) > 0)) {
+ my $dpkgmsg = _g("ERR: Unsupportable option: 'multiarch'. ".
+ "Current dpkg version does not support MultiArch. ");
+ warn $dpkgmsg;
+ die ("\n");
+ }
+ }
+ foreach $section (sort keys %keys) {
+ if ($section ne "general") {
$sources{$section}=$keys{$section}{'source'} if (not exists $source{$section});
# don't set suite or component if URL is of apt-ftparchive trailing-slash form
# regexp is: optional string in '[]', string without '[' or ']', string ending in '/'
$flatfile{$section}++ if (($sources{$section} =~ /^(\[.*\] )*[^\[\]]+ .+\/$/));
- if ((exists $keys{$section}{'architecture'}) and
- ($keys{$section}{'architecture'} ne "")) {
- my $frgn_arch = $keys{$section}{'architecture'};
+ $suites{$section}=$keys{$section}{'suite'}
+ if (not exists $suites{$section});
+ $components{$section}=$keys{$section}{'components'}
+ if (not exists $components{$section});
+ $components{$section}='main'
+ if (not defined $components{$section});
+ $arches{$section}=$keys{$section}{'arch'}
+ if (not exists $arches{$section});
+ $arches{$section}=$arch
+ if (not defined $arches{$section} or $arches{$section} eq "");
+ $multiarches{$section}=$keys{$section}{'multiarch'}
+ if (not exists $multiarches{$section});
+ $multiarches{$section}=""
+ if (not defined $multiarches{$section});
+ {
+ my @pkglist=();
my @tmp=();
if (ref ($keys{$section}{'packages'}) eq 'ARRAY') {
- foreach my $p (@{$keys{$section}{'packages'}}) {
- push @tmp, "$p:$frgn_arch";
- push @req_arches, $frgn_arch;
- }
+ push @pkglist, @{$keys{$section}{'packages'}};
} else {
- foreach my $p (split(' ', $keys{$section}{'packages'})) {
- push @tmp, "$p:$frgn_arch";
- push @req_arches, $frgn_arch;
- }
- }
- if ($olddpkg == 0) {
- $packages{$section} = join(' ', @tmp);
- } else {
- my $dpkgmsg = sprintf (_g("ERR: Unsupportable option: 'architecture'. ".
- "Current dpkg version does not support MultiArch. ".
- "Packages for '%s' have been ignored.\n"), $section);
- warn $dpkgmsg;
- $warn_count++;
+ push @pkglist, $keys{$section}{'packages'};
}
- } else {
- if (ref ($keys{$section}{'packages'}) eq 'ARRAY') {
- $packages{$section}=join(' ', @{$keys{$section}{'packages'}});
- } else {
- $packages{$section}=join(' ', $keys{$section}{'packages'});
+ my $pkgname;
+ my $pkgarch;
+ foreach my $p (@pkglist) {
+ if ($p =~ /^([^:]+):([^:]+)$/) {
+ ($pkgname = $p) =~ s/^([^:]+):([^:]+)$/$1/;
+ ($pkgarch = $p) =~ s/^([^:]+):([^:]+)$/$2/;
+ } else {
+ $pkgname = $p;
+ $pkgarch = $arches{$section};
+ }
+ if ($pkgarch eq $arch) {
+ push @tmp, "$pkgname";
+ } else {
+ push @tmp, "$pkgname:$pkgarch";
+ push @req_arches, $pkgarch;
+ }
}
+ $packages{$section} = join(' ', @tmp);
}
- $suites{$section}=$keys{$section}{'suite'}
- if (not exists $suites{$section} and not exists $flatfile{$section});
- $components{$section}=$keys{$section}{'components'}
- if (not exists $components{$section} and not exists $flatfile{$section});
- $omitdebsrc{$section}=$section if ((defined $keys{$section}{'omitdebsrc'})
- and ($keys{$section}{'omitdebsrc'} eq "true"));
push @reinstall, split (/ /, lc($keys{$section}{'reinstall'}))
if (defined $keys{$section}{'reinstall'});
- $components{$section}='main' if (not defined $components{$section});
- $keyrings{$section}=$keys{$section}{'keyring'} if (not exists $keyrings{$section});
push @extrapkgs, split (' ', lc($keys{$section}{'additional'}))
if (defined $keys{$section}{'additional'});
+ $omitdebsrc{$section}=$section
+ if ((defined $keys{$section}{'omitdebsrc'}) and ($keys{$section}{'omitdebsrc'} eq "true"));
+ $keyrings{$section}=$keys{$section}{'keyring'}
+ if (not exists $keyrings{$section});
+ if ($olddpkg != 0 && $multiarches{$section} ne "") {
+ my $dpkgmsg = sprintf (_g("ERR: Unsupportable option: 'multiarch'. ".
+ "Current dpkg version does not support MultiArch. "));
+ warn $dpkgmsg;
+ die ("\n");
+ }
}
}
my %archchk=();
@@ -1301,9 +1300,9 @@ sub cascade {
foreach my $req (@req_arches) {
if (not exists $archchk{$req}) {
# Translators: %1 and %2 are the same value here - the erroneous architecture name
- my $reqmsg = sprintf (_g("ERR: Misconfiguration in: 'architecture' option. ".
- "Packages of architecture=%s requested but '%s' is not included in the multiarch=".
- join (" ", @foreignarches) . " option.\n"), $req, $req);
+ my $reqmsg = sprintf(_g("ERR: Misconfiguration in: 'architecture' option. ".
+ "Packages of architecture=%s requested but '%s' is not included in the multiarch=".
+ join (" ", @foreignarches) . " option.\n"), $req, $req);
warn $reqmsg;
die ("\n");
}
@@ -1314,7 +1313,7 @@ sub cascade {
# returns zero on success, non-zero on fail
sub check_multiarch_dpkg {
- my $retval = system ("dpkg --print-foreign-architectures > /dev/null 2>&1");
+ my $retval = system ("dpkg --assert-multi-arch >/dev/null 2>&1");
$retval >>=8;
return $retval;
}
diff --git a/pod/multistrap b/pod/multistrap
index b511fa51..59b3a725 100644
--- a/pod/multistrap
+++ b/pod/multistrap
@@ -823,45 +823,64 @@ people on the debian-embedded@lists.debian.org mailing list and
does not parse correctly. You would need to put the C<--simulate> output
on a pastebin website and put the URL in your message.
-=head1 MultiArch support
+=head1 Multiarch Support
Multiarch support is experimental - please report issues and file bugs
with full details of your setup, the full multistrap config file and
the errors reported.
-C<multistrap> overrides the existing multiarch support of the external
-system so that a MultiArch aware system can still create a non-MultiArch
-chroot from repositories which do not support all of the architectures
-supported by the external dpkg.
+Multiarch support in C<multistrap> depends on a multiarch-capable dpkg
+in the external system, but it does not require multiarch to be enabled
+on it. You can create a multiarch C<multistrap> configuration on a
+non-multiarch system, or a non-multiarch C<multistrap> configuration on
+a multiarch system.
-If multiarch is enabled within the multistrap chroot, C<multistrap>
-writes out the list into F</var/lib/dpkg/arch> inside the chroot.
+For multiple foreign architectures, specify the option once and use a
+space separated list of architectures. You do not need to add the base
+architecture to the multiarch list.
-For multiple architectures, specify the option once and use a space
-separated list for the architecture list. Ensure you include what will
-be the host architecture of the chroot.
+Note that the C<multiarch> option in the [General] section only enables
+multiarch in dpkg, not in apt. For that you need to either provide a
+separate Section for each architecture, or add the C<multiarch> option
+to the repository Section as well.
-See also http://wiki.debian.org/Multiarch/
+The C<packages> option supports arch-qualified package names.
+Unqualified package names will be installed for the architecture
+specified in the C<arch> option of the Section, or for the base
+architecture if none is specified.
+
+The following example configuration would install the base system for
+C<amd64>; zlib1g for C<amd64> and C<sparc64>; and liblzma5 for
+C<sparc> and C<sparc64>.
[General]
...
- multiarch=i386 armel armhf
-
-Each Section will install packages from the base architecture unless
-the C<Architecture> option is specified for particular sections.
+ arch=amd64
+ multiarch=sparc sparc64
- [Foreign]
- packages=libgcc1 libc6
- architecture=armel
+ [Debian]
+ suite=sid
+ multiarch=sparc
+ packages=zlib1g liblzma5:sparc
source=http://ftp.uk.debian.org/debian
keyring=debian-archive-keyring
+
+ [DebianPorts]
suite=sid
+ architecture=sparc64
+ packages=zlib1g liblzma5
+ source=http://ftp.debian-ports.org/debian
+ keyring=debian-ports-archive-keyring
+ omitdebsrc=true
In the C<--simulate> output, the architecture(s) specified in the
MultiArch option will be listed under the "Foreign architectures"
-listing. Packages for a specific architecture will be listed as the
-package name followed by a colon followed by the architecture.
+listing. Packages for a foreign architecture will be listed as
+a architecture-qualified package name, eg the base package name
+followed by a colon followed by the architecture.
libgcc1:armel libc6:armel
+See also http://wiki.debian.org/Multiarch/
+
=cut
--
1.7.10.4
Reply to: