quirks: inject the kernel's host-tool libraries as :native for cross
The resolute and stonking kernels declare libelf-dev, libdw-dev and libssl-dev unqualified, unlike the Debian control which carries the same names qualified :native for the host-side tools (resolve_btfids, gendwarfksyms, sign-file). The dpkg cross rules resolve an unqualified Multi-Arch: same name against the host architecture only, so a cross build installs no build-architecture variants and the kernel's host-side tools cannot link (-ldw, -lelf, -lssl all fail). Inject the :native variants for the affected series — the declared unqualified dependencies stay, so the target-side tools keep their host-architecture libraries. Series-scoped so the entry can be dropped once the control is fixed upstream.
This commit is contained in:
@@ -15,18 +15,38 @@ quirks:
|
|||||||
# against the host architecture, whose dependency closure conflicts with
|
# against the host architecture, whose dependency closure conflicts with
|
||||||
# the `:native` python3. Resolve it against the build architecture
|
# the `:native` python3. Resolve it against the build architecture
|
||||||
# until the control is fixed upstream.
|
# until the control is fixed upstream.
|
||||||
|
# The resolute and stonking kernels declare the host-tool libraries
|
||||||
|
# unqualified (libelf-dev for resolve_btfids, libdw-dev for
|
||||||
|
# gendwarfksyms, libssl-dev for sign-file), unlike the Debian control,
|
||||||
|
# which carries the same names qualified `:native`. The dpkg cross
|
||||||
|
# rules resolve an unqualified Multi-Arch: same name against the host
|
||||||
|
# architecture only, so a cross build installs no build-architecture
|
||||||
|
# variants and the kernel's host-side tools cannot link. Inject the
|
||||||
|
# build-architecture variants until the control is fixed upstream.
|
||||||
linux:
|
linux:
|
||||||
deb:
|
deb:
|
||||||
- series: [resolute]
|
- series: [resolute]
|
||||||
dependencies:
|
dependencies:
|
||||||
replace:
|
replace:
|
||||||
llvm-21-dev: llvm-21-dev:native <!stage1>
|
llvm-21-dev: llvm-21-dev:native <!stage1>
|
||||||
|
- series: [resolute, stonking]
|
||||||
|
dependencies:
|
||||||
|
inject:
|
||||||
|
- libelf-dev:native
|
||||||
|
- libdw-dev:native
|
||||||
|
- libssl-dev:native
|
||||||
linux-riscv:
|
linux-riscv:
|
||||||
deb:
|
deb:
|
||||||
- series: [resolute]
|
- series: [resolute]
|
||||||
dependencies:
|
dependencies:
|
||||||
replace:
|
replace:
|
||||||
llvm-21-dev: llvm-21-dev:native <!stage1>
|
llvm-21-dev: llvm-21-dev:native <!stage1>
|
||||||
|
- series: [resolute, stonking]
|
||||||
|
dependencies:
|
||||||
|
inject:
|
||||||
|
- libelf-dev:native
|
||||||
|
- libdw-dev:native
|
||||||
|
- libssl-dev:native
|
||||||
|
|
||||||
# Add more packages and their quirks as needed
|
# Add more packages and their quirks as needed
|
||||||
# example-package:
|
# example-package:
|
||||||
|
|||||||
+48
-1
@@ -265,15 +265,62 @@ mod tests {
|
|||||||
fn linux_dependency_quirks_are_series_scoped() {
|
fn linux_dependency_quirks_are_series_scoped() {
|
||||||
for package in ["linux", "linux-riscv"] {
|
for package in ["linux", "linux-riscv"] {
|
||||||
let rules = get_deb_dependency_quirks(package, "resolute");
|
let rules = get_deb_dependency_quirks(package, "resolute");
|
||||||
assert_eq!(rules.len(), 1, "the resolute entry applies");
|
assert_eq!(rules.len(), 2, "the resolute entries apply");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
rules[0].replace.get("llvm-21-dev").map(String::as_str),
|
rules[0].replace.get("llvm-21-dev").map(String::as_str),
|
||||||
Some("llvm-21-dev:native <!stage1>")
|
Some("llvm-21-dev:native <!stage1>")
|
||||||
);
|
);
|
||||||
|
// Only the stonking entry exists there: the llvm-21-dev
|
||||||
|
// replacement above is a resolute-only packaging state.
|
||||||
|
let rules = get_deb_dependency_quirks(package, "stonking");
|
||||||
|
assert_eq!(rules.len(), 1);
|
||||||
|
assert!(rules[0].replace.is_empty());
|
||||||
assert!(get_deb_dependency_quirks(package, "noble").is_empty());
|
assert!(get_deb_dependency_quirks(package, "noble").is_empty());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// The kernels of the series whose control dropped the Debian-style
|
||||||
|
/// `:native` qualifiers on the host-tool libraries inject the
|
||||||
|
/// build-architecture variants: the dpkg cross rules resolve the
|
||||||
|
/// unqualified Multi-Arch: same names against the host architecture
|
||||||
|
/// only, leaving nothing for the kernel's host-side tools to link.
|
||||||
|
#[test]
|
||||||
|
fn linux_injects_native_host_tool_libraries_for_cross() {
|
||||||
|
for series in ["resolute", "stonking"] {
|
||||||
|
let mut clauses = vec![vec![parse("libelf-dev <!stage1>")]];
|
||||||
|
crate::quirks::apply_dependency_quirks("linux", series, &mut clauses, &opts()).unwrap();
|
||||||
|
let injected: Vec<&PkgRelation> = clauses[1..]
|
||||||
|
.iter()
|
||||||
|
.flatten()
|
||||||
|
.filter(|rel| {
|
||||||
|
["libelf-dev", "libdw-dev", "libssl-dev"].contains(&rel.package.as_str())
|
||||||
|
})
|
||||||
|
.collect();
|
||||||
|
assert_eq!(
|
||||||
|
injected.len(),
|
||||||
|
3,
|
||||||
|
"one :native clause per host-tool library"
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
injected
|
||||||
|
.iter()
|
||||||
|
.all(|rel| rel.arch_qualifier.as_deref() == Some("native"))
|
||||||
|
);
|
||||||
|
// The declared dependency itself is untouched: the host
|
||||||
|
// (target) variant still installs for the checker.
|
||||||
|
assert_eq!(clauses[0][0].arch_qualifier, None);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Other kernel series keep their declared dependencies untouched.
|
||||||
|
#[test]
|
||||||
|
fn noble_linux_dependencies_are_not_rewritten() {
|
||||||
|
let mut clauses = vec![vec![parse("libelf-dev")]];
|
||||||
|
crate::quirks::apply_dependency_quirks("linux", "noble", &mut clauses, &opts()).unwrap();
|
||||||
|
assert_eq!(clauses.len(), 1);
|
||||||
|
assert_eq!(clauses[0][0].arch_qualifier, None);
|
||||||
|
}
|
||||||
|
|
||||||
/// `replace` rewrites exactly the dependencies whose declared name
|
/// `replace` rewrites exactly the dependencies whose declared name
|
||||||
/// matches, wholesale: the replacement carries its own qualifier and
|
/// matches, wholesale: the replacement carries its own qualifier and
|
||||||
/// restrictions.
|
/// restrictions.
|
||||||
|
|||||||
Reference in New Issue
Block a user