"Fabian" == Fabian Grünbichler <debian@fabian.gruenbichler.email> writes:
Hi,
I'm writing this mail in order to get further input from knowledgeable, but not directly involved DDs - mostly those involved with cross-building and multi-arch matters.
Some background for those not familiar with rust packaging in Debian, skip below for the actual examples and question.crates.io, building one or more librust-foo*-dev binary packages that actually contain the crate's (patched) source code, and in case of a "bin" crate shipping an actual program/application, a binary package containing the compiled executable + support
The debian-rust team uses a rather unified workflow to build a large amount of rust library crates and a not-quite-as-large amount of binary crates/applications. Each source package (rust-foo) corresponds to a single crate (rust package) released on
E.g., a crate foo that depends on a crate bar which in turn depends on a crate baz will have the foo->bar relationship encoded as build-dependency (rust-foo -> librust-bar-dev) and dependency (librust-foo-dev -> librust-bar-dev, for packages [build-]depending on crate foo), while the bar->baz dependency will *only* be encoded as regular dependency (librust-bar-dev -> librust-baz-dev) in rust-foo's dependency tree.
debcargo, the tool used by the Debian rust team to streamline the work of transforming upstream crates into Debian source packages generates d/control entries for librust-* binary packages qualified as arch:any and M-A:same, in order to support crosscompilation. This solution was suggested by dpkg developers (Guillem?) according to the following comment left in the debcargo source code:
// This is the best but not ideal option for us.packages from arch:any, M-A:same (like the rust team's) to arch:all, M-A:foreign. There was no agreement between the Debian rust team and Jonas whether this change is problematic and should be reverted (or not), after a bit of discussion we agreed on
//
// Currently Debian M-A spec has a deficiency where a package X that
// build-depends on a (M-A:foreign+arch:all) package that itself
// depends on an arch:any package Z, will pick up the BUILD_ARCH of
// package Z instead of the HOST_ARCH. This is because we currently
// have no way of telling dpkg to use HOST_ARCH when checking that the
// dependencies of Y are satisfied, which is done at install-time
// without any knowledge that we're about to do a cross-compile. It
// is also problematic to tell dpkg to "accept any arch" because of
// the presence of non-M-A:same packages in the archive, that are not
// co-installable - different arches of Z might be depended-upon by
// two conflicting chains. (dpkg has so far chosen not to add an
// exception for the case where package Z is M-A:same co-installable).
//
// The recommended work-around for now from the dpkg developers is to
// make our packages arch:any M-A:same even though this results in
// duplicate packages in the Debian archive. For very large crates we
// will eventually want to make debcargo generate -data packages that
// are arch:all and have the arch:any -dev packages depend on it.
https://salsa.debian.org/rust-team/debcargo/-/blob/master/src/debian/control.rs#L342
Some time ago, Jonas (CCed) started packaging rust crates in the same "namespace" (src:rust-foo building bin:librust-foo-*) using a slightly different approach, but in a *mostly* compatible fashion. More recently, Jonas started switching over his rust
One example of a working in practice (as in, the build doesn't fail), but technically wrong (cross-)build (pulls in dependencies from wrong architecture) can be found here:serde-dev (arch:any, but wrongly resolved!)
https://paste.debian.net/1270516/
The chain is
rust-lscolors (arch:any) --BD--> librust-tempfile-dev (arch:any) librust-tempfile-dev (arch:any) --D--> librust-remove-dir-all-0.7+default-dev (arch:any) --D--> librust-log-0.4+default-dev (arch:any) --D--> librust-value-bag-1.0.0+serde-dev (arch:any) --D--> librust-serde-fmt-1+default-dev (arch:all) --D--> librust-
with librust-serde-fmt-dev being switched to arch:all, it will resolve to :amd64 instead of :i386 and in turn pull in its own dependencies librust-serde-1+std-dev & librust-serde-1-dev (both provided by librust-serde-dev) from amd64 (in addition tolibrust-serde-dev:i386, which is also part of the arch:any (build-)dependency tree of rust-lscolors itself, without the "hop" over librust-serde-fmt-dev).
src:rust-lscolors was taken as minimal example bin crate here - many rust binary crates are affected by this issue since a few crates which are part of common dependency chains are maintained by Jonas and recently got switched to arch:all (serde-fmtand ahash are the two most prominent). Note that much of the rust ecosystem relies on a crate called bindgen to generate rust bindings for C libraries, which in turn leverages clang under the hood, which unfortunately makes those packages currently not
Another example would be src:rust-hashbrown, which directly build-depends on librust-ahash-0.7-dev which got switched to arch:all, cross building it on an amd64 machine for i386 withi386.
DEB_BUILD_OPTIONS='' sbuild -c debian-unstable-amd64-sbuild -d unstable --host i386 --profiles cross rust-hashbrown_0.12.3-1.dsc
will pull in all librust-* packages from the wrong architecture (am64 instead of i386):
$ grep -E '^Get.*librust-serde' rust-hashbrown_0.12.3-1_i386.build
Get:144 http://deb.debian.org/debian unstable/main amd64 librust-cfg-if-dev amd64 1.0.0-1 [10.4 kB]
Get:145 http://deb.debian.org/debian unstable/main amd64 librust-libc-dev amd64 0.2.139-1 [290 kB]
[ .. snip lots of librust-*-dev amd64 downloads ..]
Get:170 http://deb.debian.org/debian unstable/main amd64 librust-version-check-dev amd64 0.9.4-1 [15.9 kB]
Get:171 http://deb.debian.org/debian unstable/main amd64 librust-ahash-0.7-dev all 0.7.6-11 [477 kB]
Reverting librust-ahash-0.7-dev to arch:any, M-A:same (and injecting both the resulting amd64 and i386 package into the build env, to override the arch:all one from the archive) makes the cross-build correctly only pull in librust-*-dev packages from
TL;DR: Is the switch to arch:all one that should be reverted in the face of it apparently breaking cross builds? Or is there another alternative (nowadays) that makes the "workaround" employed by debcargo no longer needed?option for debcargo-managed packages as well, and which changes on the team tooling side are needed to avoid losing test coverage or increasing friction.
Depending on feedback, the rust team would either ask Jonas to switch back his packages to arch:any, M-A:same (probably after bookworm, to prevent further fallout/need for RMs/.. during the freeze), or will evaluate whether switching to arch:all is an
Thanks for reading and any informed input,
Fabian
<div><a href="https://salsa.debian.org/rust-team/debcargo/-/blob/master/src/debian/control.rs#L342">https://salsa.debian.org/rust-team/debcargo/-/blob/master/src/debian/control.rs#L342</a><br></div><div><br></div><div>Some time ago, Jonas (CCed)started packaging rust crates in the same "namespace" (src:rust-foo building bin:librust-foo-*) using a slightly different approach, but in a *mostly* compatible fashion. More recently, Jonas started switching over his rust packages from arch:any, M-A:
<div>will pull in all librust-* packages from the wrong architecture (am64 instead of i386):<br></div><div><br></div><div>$ grep -E '^Get.*librust-serde' rust-hashbrown_0.12.3-1_i386.build<br></div><div><br></div><div>Get:144 <a href="http://deb.debian.org/debian">http://deb.debian.org/debian</a> unstable/main amd64 librust-cfg-if-dev amd64 1.0.0-1 [10.4 kB]<br></div><div>Get:145 <a href="http://deb.debian.org/debian">http://deb.debian.org/debian</a> unstable/main amd64 librust-libc-dev amd64 0.
<div>Get:171 <a href="http://deb.debian.org/debian">http://deb.debian.org/debian</a> unstable/main amd64 librust-ahash-0.7-dev all 0.7.6-11 [477 kB]<br></div><div><br></div><div>Reverting librust-ahash-0.7-dev to arch:any, M-A:same (and injectingboth the resulting amd64 and i386 package into the build env, to override the arch:all one from the archive) makes the cross-build correctly only pull in librust-*-dev packages from i386.<br></div><div><br></div><div>TL;DR: Is the switch to arch:all one
"Fabian" == Fabian Grünbichler <debian@fabian.gruenbichler.email> writes:
Fabian> On Wed, Feb 15, 2023, at 7:51 PM, Fabian Grünbichler wrote:
>> Hi,
>>
>> I'm writing this mail in order to get further input from
>> knowledgeable, but not directly involved DDs - mostly those
>> involved with cross-building and multi-arch matters.
Fabian> sorry for the noise - now with correct CC of
Fabian> debian-cross@lists.debian.org, instead of the mis-pasted
Fabian> d-cross@ ..
A couple of questions that aren't obvious to me:
1) Is my understanding generally correct that it mostly doesn't matter
if you get the wrong architecture's package for a rust library package,
since it's the same source code in both cases?
2) When does it matter which architecture's packages you get for rust
library packages?
3) When do rust library packages have dependencies on other kinds of >packages--packages that have more than source code?
Fabian> All in all it seems to me like the problem currently is more"Fabian" == Fabian Grünbichler <debian@fabian.gruenbichler.email> writes:
debcargo, the tool used by the Debian rust team to streamline the work
of transforming upstream crates into Debian source packages generates d/control entries for librust-* binary packages qualified as arch:any
and M-A:same, in order to support cross compilation. This solution was suggested by dpkg developers (Guillem?) according to the following
comment left in the debcargo source code:
// This is the best but not ideal option for us.
//
// Currently Debian M-A spec has a deficiency where a package X that
// build-depends on a (M-A:foreign+arch:all) package that itself
// depends on an arch:any package Z, will pick up the BUILD_ARCH of
// package Z instead of the HOST_ARCH. This is because we currently
// have no way of telling dpkg to use HOST_ARCH when checking that the
// dependencies of Y are satisfied, which is done at install-time
// without any knowledge that we're about to do a cross-compile. It
// is also problematic to tell dpkg to "accept any arch" because of
// the presence of non-M-A:same packages in the archive, that are not
// co-installable - different arches of Z might be depended-upon by
// two conflicting chains. (dpkg has so far chosen not to add an
// exception for the case where package Z is M-A:same co-installable).
//
// The recommended work-around for now from the dpkg developers is to
// make our packages arch:any M-A:same even though this results in
// duplicate packages in the Debian archive. For very large crates we
// will eventually want to make debcargo generate -data packages that
// are arch:all and have the arch:any -dev packages depend on it.
https://salsa.debian.org/rust-team/debcargo/-/blob/master/src/debian/control.rs#L342
Fabian> All in all it seems to me like the problem currently is more"Fabian" == Fabian Grnbichler <debian@fabian.gruenbichler.email> writes:
Fabian> a theoretical one - it doesn't seem to cause (much, if at
Fabian> all) additional breakage on top of stuff that is already not
Fabian> cross compilable at the moment for other reasons.
It seems like if a librust-* package depended on some system library it
had a binding for, that's going to be a problem once the binding
generation works cross-compiled. Because if I'm understanding correctly
once you manage to get onto the wrong architecture's dependencies, you
will continue to use the wrong architecture.
However, adding a question to the mix, why does arch all work for go packages?
However, adding a question to the mix, why does arch all work for go packages?
Do they not care about cross compilation, or are concerns somehow
different there?
Sam Hartman <hartmans@debian.org> 于 2023年2月16日周四 06:37写道:
However, adding a question to the mix, why does arch all work for go
packages?
Do they not care about cross compilation, or are concerns somehow
different there?
Go doesn't work. I guess we started from the common sense that
arch-indepent files should be arch:all. Or at that time Multi-Arch is not widely recognized.
<div dir="auto">(Sent from my mobile device)</div><div class="gmail_quote" dir="auto"></div></div>
On Wed, Feb 15, 2023 at 08:14:17PM +0100, Fabian Grünbichler wrote:
TL;DR: Is the switch to arch:all one that should be reverted in the face of it apparently breaking cross builds? Or is there another alternative (nowadays) that makes the "workaround" employed by debcargo no longer needed?
Yes, the switch to arch:all needs to be reverted at least partially.
Could it be that Jonas picked up such hints and thus added m-a:foreign?
Then later a C binding was added to the mix, which broke the hint, but
the conversion wasn't reverted.
This suggests that the hinter should gain another condition to never
issue arch:all+m-a:foreign conversion hints for librust-*-dev packages.
Do you agree?
// This is the best but not ideal option for us.
//
// Currently Debian M-A spec has a deficiency where a package X that
// build-depends on a (M-A:foreign+arch:all) package that itself
// depends on an arch:any package Z, will pick up the BUILD_ARCH of
// package Z instead of the HOST_ARCH. This is because we currently
// have no way of telling dpkg to use HOST_ARCH when checking that the
// dependencies of Y are satisfied, which is done at install-time
// without any knowledge that we're about to do a cross-compile. It
// is also problematic to tell dpkg to "accept any arch" because of
// the presence of non-M-A:same packages in the archive, that are not
// co-installable - different arches of Z might be depended-upon by
// two conflicting chains. (dpkg has so far chosen not to add an
// exception for the case where package Z is M-A:same co-installable).
//
// The recommended work-around for now from the dpkg developers is to
// make our packages arch:any M-A:same even though this results in
// duplicate packages in the Debian archive. For very large crates we
// will eventually want to make debcargo generate -data packages that
// are arch:all and have the arch:any -dev packages depend on it.
https://salsa.debian.org/rust-team/debcargo/-/blob/master/src/debian/control.rs#L342
librust-serde-dev (arch:any, but wrongly resolved!)The chain is
rust-lscolors (arch:any) --BD--> librust-tempfile-dev (arch:any) librust-tempfile-dev (arch:any) --D--> librust-remove-dir-all-0.7+default-dev (arch:any) --D--> librust-log-0.4+default-dev (arch:any) --D--> librust-value-bag-1.0.0+serde-dev (arch:any) --D--> librust-serde-fmt-1+default-dev (arch:all) --D-->
librust-serde-dev:i386, which is also part of the arch:any (build-)dependency tree of rust-lscolors itself, without the "hop" over librust-serde-fmt-dev).with librust-serde-fmt-dev being switched to arch:all, it will resolve to :amd64 instead of :i386 and in turn pull in its own dependencies librust-serde-1+std-dev & librust-serde-1-dev (both provided by librust-serde-dev) from amd64 (in addition to
TL;DR: Is the switch to arch:all one that should be reverted in the face of it apparently breaking cross builds? Or is there another alternative (nowadays) that makes the "workaround" employed by debcargo no longer needed?
an option for debcargo-managed packages as well, and which changes on the team tooling side are needed to avoid losing test coverage or increasing friction.Depending on feedback, the rust team would either ask Jonas to switch back his packages to arch:any, M-A:same (probably after bookworm, to prevent further fallout/need for RMs/.. during the freeze), or will evaluate whether switching to arch:all is
I don't see a need for such general rule for all librust-*-dev packages.
E.g. librust-futures-timer-dev and librust-event-listener-dev has no dependencies so should be safe to distribute as arch-all and marked as m-a:foreign, right?
Sure, there is a theoretical risk that some day in the future those
packages grow dependencies that require changing that, but isn't that
the case generally for m-a hinting?
I guess it makes sense instead to have a lintian warning for packages
marked m-a:foreign that all its dependencies are equally marked (or if
that's unreasonably expensive then check only one level deep). That
should help flag misuses of m-a:foreign including this one of mine (for
most but not all the librust-*-dev packages that I maintain).
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 300 |
Nodes: | 16 (2 / 14) |
Uptime: | 32:20:47 |
Calls: | 6,707 |
Files: | 12,239 |
Messages: | 5,353,197 |