It has become clear that dpkg-cross need to be able to cross multiarch packages as well as conventional ones. This is because we cannot yet have cross-arch dependencies to let us simply depend on necessary cross-libraries, and an arch all package (such as dpkg-cross makes) cannot install files in the multiarch /usr/lib/<triplet> location according to multiarch policy (because they could clash with the files from the real architecture).
This was not really on the roadmap, where we simple expected to be able to use multiarch packages for crossing-aginst as-is, but we're not quite there yet. Here is a patch to provide that functionality without being too hacky. It also removes all the X11R6 directory special-casing as that is long-gone. dpkg-cross will not convert a multiarch package unless --convert-multiarch is passed to force it to do so. It is possible there are still missing fixups needed in pkgconfig and .la fixup functions, but I've not found any in the tests I've done so far. This has been tested against these ubuntu natty packages: Multi-Arch: libc6_2.13-0ubuntu8_amd64.deb libc6-dev_2.13-0ubuntu8_amd64.deb libfreetype6_2.4.4-1ubuntu2_amd64.deb libfreetype6-dev-2.4.4-1ubuntu2_all.deb (note: this package is not right because it is not marked Multi-Arch but has its files in multiarch locations - this breaks dpkg-cross's behaviour and some files are missed out. I think that's OK.) pre-multiarch: libc6_2.13-0ubuntu1_amd64.deb libc6-dev_2.13-0ubuntu1_amd64.deb libfreetype6_2.4.4-1_amd64.deb libfreetype6-dev_2.4.4-1_amd64.deb Index: dpkg-cross =================================================================== RCS file: /cvsroot/dpkg-cross/dpkg-cross/dpkg-cross,v retrieving revision 1.83 diff -u -r1.83 dpkg-cross --- dpkg-cross 23 Feb 2011 14:46:33 -0000 1.83 +++ dpkg-cross 25 Mar 2011 15:37:06 -0000 @@ -14,7 +14,7 @@ @keepdeps $dpkg_statfile $progname $debname $anyway $cross2cross $crossdir $crosslib $crosslib64 $crosslib32 $crossinc $data $len $retval $dpkg_cmd $mode $pkg @exlist $conffile $removedeps $keepdeps -$DPKGCROSSVERSION $keep_temp $msg ); +$DPKGCROSSVERSION $keep_temp $msg $multiarchpackage $multiarch $multiarchconv); setlocale(LC_MESSAGES, ""); textdomain("dpkg-cross"); @@ -262,14 +262,15 @@ -?|-h|--help|--version: print this message. Options: - -a|--arch ARCH: set architecture (default: defined in configuration file) - -v|--verbose: be verbose - -q|--quiet: be quiet - -A|--convert-anyway: convert package even if it does not provide any - development files - -X|--exclude PACKAGE: Exclude this package from the dependency list of the - built package. - -k|--keep-temp: Keep the temporary archives when installing. + -a|--arch ARCH: set architecture (default: defined in configuration file) + -v|--verbose: be verbose + -q|--quiet: be quiet + -A|--convert-anyway: convert package even if it does not provide any + development files + -M|--convert-multiarch: convert package even if it is a multiarch package + -X|--exclude PACKAGE: Exclude this package from the dependency list of the + built package. + -k|--keep-temp: Keep the temporary archives when installing. dpkg-cross installs or removes libraries and include files for cross-compiling Debian packages. It reads /etc/dpkg-cross/cross-compile @@ -334,6 +335,8 @@ push @removedeps, $pkg; } elsif (/^(-A|--convert-anyway)$/) { $anyway = 1; + } elsif (/^(-A|--convert-multiarch)$/) { + $multiarchconv = 1; } else { die sprintf (_g("%s: Unknown option %s.\n"), $progname, $_); } @@ -507,18 +510,24 @@ } close(CONTROL); - if (defined ($control{'multi-arch'})) { - my $output = basename ($package); - warn sprintf(_g("%s: Skipping the '%s' Multi-Arch package.\n"), $progname, $output); - if (not -f $output) { - open(CP, "$package"); - my @cp=<CP>; - close (CP); - open (CP, ">$output"); - print CP @cp; - close (CP); + if (defined ($control{'multi-arch'})) { + if ($multiarchconv) { + # Carry on and process file anyway if --convert-multiarch given + warn sprintf(_g("%s: Multi-Arch package detected; processing anyway as --convert-mulitarch specified.\n"), $progname); + $multiarchpackage=1; + } else { + my $output = basename ($package); + warn sprintf(_g("%s: Skipping the '%s' Multi-Arch package.\n"), $progname, $output); + if (not -f $output) { + open(CP, "$package"); + my @cp=<CP>; + close (CP); + open (CP, ">$output"); + print CP @cp; + close (CP); + } + exit 0; } - exit 0; } # check for existence of required fields for $field (qw(package version architecture)) { @@ -548,7 +557,7 @@ # prepare destination filename my $evers = $control{"version"}; $evers =~ s/^\d+://; # strip epoch for filename - $debname = $control{"package"} . "-" . $arch . "-cross_" . $evers . "_all.deb"; + $debname = $control{"package"} . "-" . $arch . "-cross_" . $evers . "_all.deb"; # now ready to start preparing destination package @@ -602,6 +611,7 @@ # Helper: fix ldscript. # Change any occurance of /lib, /usr/lib and /usr/X11R6/lib to $crosslib + # Uses global $multiarch regexp modifier sub fix_ldscript { my ($from, $to) = @_; ensure_dir($to) or return 0; @@ -617,7 +627,7 @@ return 0; } while (<FROM>) { - s:(^|[^-\w/])(/usr(/X11R6)?)?/lib:$1$crosslib:g; + s:(^|[^-\w/])(/usr)?/lib/$multiarch:$1$crosslib/:g; print TO; } close(FROM); @@ -713,6 +723,8 @@ $crosslib = $$config{'crosslib'}; $crosslib64 = $$config{'crosslib64'}; $crosslib32 = $$config{'crosslib32'}; + # add extra regexp component for multiarch packages + if ($multiarchpackage) { $multiarch="\Q$crosstype/\E" } else {$multiarch=""}; # Now process regular files ... open(PIPE, "find $src/ -type f -print |") or goto fail; @@ -757,26 +769,26 @@ } close(FROM); close(TO); - } elsif (m:^/usr(/X11R6)?/include/:) { - # regular file under /usr/include or /usr/X11R6/include + } elsif (m:^/usr/include/($multiarch)?:) { + # regular file under /usr/include/ or /usr/include/<triplet> link_file("$src$_", "$dst$crossinc/$'") or goto fail; - } elsif (m:^/usr/(lib/.*\.([hH]|[hH][hH]|[hH][pP][pP]))$:) { + } elsif (m:^/usr/(lib/$multiarch.*\.([hH]|[hH][hH]|[hH][pP][pP]))$:) { # regular .h, .hh, or .hpp file under /usr/lib link_file("$src$_", "$dst$crossdir/$1") or goto fail; - } elsif (m:^/usr(/X11R6)?/lib/([^/]+\.[ao])$:) { - # regular .a or .o file under /usr/lib or /usr/X11R6/lib - link_file("$src$_", "$dst$crosslib/$2") or goto fail; - } elsif (m:^/usr(/X11R6)?/lib64/([^/]+\.[ao])$:) { - # regular .a or .o file under /usr/lib64 or /usr/X11R6/lib64 - link_file("$src$_", "$dst$crosslib64/$2") or goto fail; - } elsif (m:^/usr(/X11R6)?/lib32/([^/]+\.[ao])$:) { - # regular .a or .o file under /usr/lib32 or /usr/X11R6/lib32 - link_file("$src$_", "$dst$crosslib32/$2") or goto fail; + } elsif (m:^/usr/lib/$multiarch([^/]+\.[ao])$:) { + # regular .a or .o file under /usr/lib + link_file("$src$_", "$dst$crosslib/$1") or goto fail; + } elsif (m:^/usr/lib64/([^/]+\.[ao])$:) { + # regular .a or .o file under /usr/lib64 + link_file("$src$_", "$dst$crosslib64/$1") or goto fail; + } elsif (m:^/usr/lib32/([^/]+\.[ao])$:) { + # regular .a or .o file under /usr/lib32 + link_file("$src$_", "$dst$crosslib32/$1") or goto fail; } elsif ((m:^/emul/ia32-linux/usr/lib/([^/]+\.[ao])$:)) { # regular .a or .o file under /emul/ia32-linux/ for #463588 link_file("$src$_", "$dst$crosslib32/$1") or goto fail; - } elsif (m:^(/usr(/X11R6)?)?/lib/([^/]+\.so[^/]*)$:) { - # regular .so* file under /lib, /usr/lib or /usr/X11R6/lib + } elsif (m:^(/usr)?/lib/($multiarch)?([^/]+\.so[^/]*)$:) { + # regular .so* file under /lib, /usr/lib, /lib/<triplet>, /usr/lib/<triplet> if (is_ldscript("$src$_")) { fix_ldscript("$src$_", "$dst$crosslib/$3") or goto fail; } else { @@ -789,19 +801,19 @@ } else { next; } - } elsif (m:^(/usr(/X11R6)?)?/lib64/([^/]+\.so[^/]*)$:) { - # regular .so* file under /lib64, /usr/lib64 or /usr/X11R6/lib64 + } elsif (m:^(/usr)?/lib64/([^/]+\.so[^/]*)$:) { + # regular .so* file under /lib64, /usr/lib64 if (is_ldscript("$src$_")) { - fix_ldscript("$src$_", "$dst$crosslib64/$3") or goto fail; + fix_ldscript("$src$_", "$dst$crosslib64/$2") or goto fail; } else { - link_file("$src$_", "$dst$crosslib64/$3") or goto fail; + link_file("$src$_", "$dst$crosslib64/$2") or goto fail; } - } elsif (m:^(/usr(/X11R6)?)?/lib32/([^/]+\.so[^/]*)$:) { - # regular .so* file under /lib32, /usr/lib32 or /usr/X11R6/lib32 + } elsif (m:^(/usr)?/lib32/([^/]+\.so[^/]*)$:) { + # regular .so* file under /lib32, /usr/lib32 if (is_ldscript("$src$_")) { - fix_ldscript("$src$_", "$dst$crosslib32/$3") or goto fail; + fix_ldscript("$src$_", "$dst$crosslib32/$2") or goto fail; } else { - link_file("$src$_", "$dst$crosslib32/$3") or goto fail; + link_file("$src$_", "$dst$crosslib32/$2") or goto fail; } } elsif ((m:^/emul/ia32-linux/usr/lib/([^/]+\.so[^/]*)$:)) { # regular .so* file under /emul/ia32-linux/usr/lib @@ -810,19 +822,19 @@ } else { link_file("$src$_", "$dst$crosslib32/$1") or goto fail; } - } elsif (m:^/usr(/X11R6)?/lib/([^/]+\.la)$:) { - # regular .la file under /usr/lib or /usr/X11R6/lib - fix_la_file("$src$_", "$dst$crosslib/$2", $crosslib) or goto fail; - } elsif (m:^/usr(/X11R6)?/lib64/([^/]+\.la)$:) { - # regular .la file under /usr/lib64 or /usr/X11R6/lib64 - fix_la_file("$src$_", "$dst$crosslib64/$2", $crosslib64) or goto fail; - } elsif (m:^/usr(/X11R6)?/lib32/([^/]+\.la)$:) { - # regular .la file under /usr/lib32 or /usr/X11R6/lib32 - fix_la_file("$src$_", "$dst$crosslib32/$2", $crosslib32) or goto fail; + } elsif (m:^/usr/lib/$multiarch([^/]+\.la)$:) { + # regular .la file under /usr/lib + fix_la_file("$src$_", "$dst$crosslib/$1", $crosslib) or goto fail; + } elsif (m:^/usr/lib64/([^/]+\.la)$:) { + # regular .la file under /usr/lib64 + fix_la_file("$src$_", "$dst$crosslib64/$1", $crosslib64) or goto fail; + } elsif (m:^/usr/lib32/([^/]+\.la)$:) { + # regular .la file under /usr/lib32 + fix_la_file("$src$_", "$dst$crosslib32/$1", $crosslib32) or goto fail; } elsif ((m:^/emul/ia32-linux/usr/lib/([^/]+\.la)$:)) { # regular .la file under /emul-ia32-linux/usr/lib/ fix_la_file("$src$_", "$dst$crosslib32/$1", $crosslib32) or goto fail; - } elsif (m:/usr/lib/(pkgconfig/[^/]+.pc)$:) { + } elsif (m:/usr/lib/$multiarch(pkgconfig/[^/]+.pc)$:) { # regular .pc file in /usr/lib/pkgconfig fix_pc_file("$src$_", "$dst$crosslib/$1") or goto fail; # not for lib64: I don't know if there is any rationale @@ -876,7 +888,7 @@ while(<PIPE>) { chomp; s/^$src//; - # Ignore any symlinks not under /usr or /lib or /lib64 + # Ignore any symlinks not under /usr or /lib or /lib64 (or /emul/ia32-linux) m:^/(usr|lib|lib64|emul/ia32-linux): or next; next if (m:^/usr/\w+-\w+(-\w+(-\w+)?)?/: && !$cross2cross); # Find out (absolute) symlink destination @@ -885,11 +897,12 @@ m:^(.*)/[^/]*$:; $lv = "$1/$lv"; } - # Ignore any symlinks pointing outside /usr and /lib and /lib64 + # Ignore any symlinks pointing outside /usr and /lib and /lib64 (or /emul/ia32-linux) $lv =~ m:^/(usr|lib|lib64|emul/ia32-linux): or next; + # Calculate corresponding DESTINATION path - $lv = convert_path($lv); + $lv = convert_path($multiarch,$lv); # Check if destination object exists. # FIXME: this code is not correct for the case of symlink chains. @@ -903,7 +916,7 @@ } # Calculate corresponding SOURCE path - $_ = convert_path($_); + $_ = convert_path($multiarch,$_); # Skip links that are going to point to themselves # Example is /usr/include/X11 -> ../X11R6/include/X11: @@ -1267,9 +1280,14 @@ =head1 Multiarch behaviour -C<dpkg-cross> now does nothing with packages from Debian which already +By default <dpkg-cross> does nothing with packages from Debian which already support Multi-Arch - the package is simply copied to the current work -directory, if it does not already exist. +directory, if it does not already exist. Any package containing a Multi-Arch: +field in DEBIAN/control is skipped in this manner. + +--convert-multiarch can be specified to instead force the generation of a +-<arch>-cross package with the files moved into the conventional +dpkg-cross locations. The Multiarch spec ensures that multiarch packages will only be available from Debian mirrors once dpkg itself is capable of installing @@ -1280,7 +1298,5 @@ multiarch package itself handles the header files and pkg-config files.) -Any package containing a Multi-Arch: field in DEBIAN/control is skipped -in this manner. =cut Index: Debian/DpkgCross.pm =================================================================== RCS file: /cvsroot/dpkg-cross/dpkg-cross/Debian/DpkgCross.pm,v retrieving revision 1.51 diff -u -r1.51 DpkgCross.pm --- Debian/DpkgCross.pm 23 Feb 2011 14:46:35 -0000 1.51 +++ Debian/DpkgCross.pm 25 Mar 2011 15:37:06 -0000 @@ -437,29 +437,31 @@ return $dir; } -=head1 convert_path($path) +=head1 convert_path($multiarch, $path) Convert path, substituting '$crossinc', '$crosslib', '$crosslib64', -'$crosslib32', '$crossdir'. This function will be used while building foreign -binary packages or converting GCC options. +'$crosslib32', '$crossdir', allowing for multiarch paths. This function will +be used while building foreign binary packages or converting GCC options. - $1: Directory (and file) to convert. + $1: Multiarch sub-directory to strip + $2: Directory (and file) to convert. return: Converted path. =cut sub convert_path { - my $path = &simplify_path ($_[0]); - if ($path =~ /^\/usr(\/X11R6)?\/include\//) { + my $multiarch = $_[0]; + my $path = &simplify_path ($_[1]); + if ($path =~ /^\/usr\/include\/($multiarch)?/) { $path = "$crossinc/$'"; - } elsif ($path =~ /^(\/usr(\/X11R6)?)?\/lib\//) { + } elsif ($path =~ /^(\/usr)?\/lib\/($multiarch)?/) { $path = "$crosslib/$'"; - } elsif ($path =~ /^(\/usr(\/X11R6)?)?\/lib64\//) { + } elsif ($path =~ /^(\/usr)?\/lib64\/($multiarch)?/) { $path = "$crosslib64/$'"; - } elsif ($path =~ /^(\/usr(\/X11R6)?)?\/lib32\//) { + } elsif ($path =~ /^(\/usr)?\/lib32\/($multiarch)?/) { $path = "$crosslib32/$'"; - } elsif ($path =~ m:^(/emul/ia32-linux/(usr/)?lib/):) { + } elsif ($path =~ m:^(/emul/ia32-linux/(usr/)?lib/($multiarch)?):) { $path = "$crosslib32/$'"; } elsif ($path =~ /^\/usr\/\w+-\w+(-\w+(-\w+)?)?\//) { # leave alone Index: debian/changelog =================================================================== RCS file: /cvsroot/dpkg-cross/dpkg-cross/debian/changelog,v retrieving revision 1.213 diff -u -r1.213 changelog --- debian/changelog 23 Feb 2011 14:46:36 -0000 1.213 +++ debian/changelog 25 Mar 2011 15:37:06 -0000 @@ -1,8 +1,14 @@ dpkg-cross (2.6.3) unstable; urgency=low + [ Neil Williams ] * Drop old apt-cross multiarch behaviour - outdated. - -- Neil Williams <codeh...@debian.org> Wed, 23 Feb 2011 13:54:27 +0000 + [ Wookey ] + * Add (interim) --convert-multiarch behaviour to cross even + multiarch packages (Closes: #619400) + * Drop X11R6 lib/include dirs as they are no longer present + + -- Wookey <woo...@debian.org> Fri, 25 Mar 2011 03:53:24 +0000 dpkg-cross (2.6.2) unstable; urgency=low Wookey -- Principal hats: Linaro, Emdebian, Wookware, Balloonboard, ARM http://wookware.org/ -- To UNSUBSCRIBE, email to debian-bugs-dist-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org