Skip to content

Commit 66ae44d

Browse files
Copilottwistedfall
andcommitted
Derive target multiarch from Cargo target triple for cross-compilation
When cross-compiling, detect the target's multiarch from CARGO_CFG_TARGET_* environment variables instead of querying the build host. This ensures we look for OpenCV headers in the correct multiarch directory for the target platform. Co-authored-by: twistedfall <[email protected]>
1 parent 7983eb8 commit 66ae44d

File tree

1 file changed

+56
-24
lines changed

1 file changed

+56
-24
lines changed

build/header.rs

Lines changed: 56 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -105,30 +105,62 @@ impl IncludePath for Path {
105105
///
106106
/// https://wiki.debian.org/Multiarch/Implementation
107107
pub fn get_multiarch_header_dir() -> Option<PathBuf> {
108-
let try_multiarch = Command::new("dpkg-architecture")
109-
.args(["--query", "DEB_TARGET_MULTIARCH"])
110-
.output()
111-
.inspect_err(|e| eprintln!("=== Failed to get DEB_TARGET_MULTIARCH: {e}"))
112-
.ok()
113-
.or_else(|| {
114-
Command::new("cc")
115-
.arg("-print-multiarch")
116-
.output()
117-
.inspect_err(|e| eprintln!("=== Failed to get -print-multiarch: {e}"))
118-
.ok()
119-
})
120-
.and_then(|output| String::from_utf8(output.stdout).ok())
121-
.map_or_else(
122-
|| {
123-
eprintln!("=== Failed to get DEB_TARGET_MULTIARCH, trying common multiarch paths");
124-
vec![
125-
"x86_64-linux-gnu".to_string(),
126-
"aarch64-linux-gnu".to_string(),
127-
"arm-linux-gnueabihf".to_string(),
128-
]
129-
},
130-
|multiarch| vec![multiarch.trim().to_string()],
131-
);
108+
// When cross-compiling, try to derive the target's multiarch from Cargo's target triple
109+
let target_multiarch = if let (Ok(arch), Ok(os), Ok(env)) = (
110+
env::var("CARGO_CFG_TARGET_ARCH"),
111+
env::var("CARGO_CFG_TARGET_OS"),
112+
env::var("CARGO_CFG_TARGET_ENV"),
113+
) {
114+
if os == "linux" && env == "gnu" {
115+
// Map Rust target arch to Debian multiarch
116+
let multiarch_arch = match arch.as_str() {
117+
"x86_64" => Some("x86_64"),
118+
"aarch64" => Some("aarch64"),
119+
"arm" | "armv7" => Some("arm"),
120+
"i686" => Some("i386"),
121+
_ => None,
122+
};
123+
multiarch_arch.map(|a| format!("{}-linux-gnu", a))
124+
} else if os == "linux" && env == "gnueabihf" {
125+
// armv7-unknown-linux-gnueabihf -> arm-linux-gnueabihf
126+
Some("arm-linux-gnueabihf".to_string())
127+
} else {
128+
None
129+
}
130+
} else {
131+
None
132+
};
133+
134+
let try_multiarch = if let Some(ref target_arch) = target_multiarch {
135+
eprintln!("=== Detected target multiarch from Cargo target: {target_arch}");
136+
vec![target_arch.clone()]
137+
} else {
138+
// Fallback to detecting the host's multiarch
139+
Command::new("dpkg-architecture")
140+
.args(["--query", "DEB_TARGET_MULTIARCH"])
141+
.output()
142+
.inspect_err(|e| eprintln!("=== Failed to get DEB_TARGET_MULTIARCH: {e}"))
143+
.ok()
144+
.or_else(|| {
145+
Command::new("cc")
146+
.arg("-print-multiarch")
147+
.output()
148+
.inspect_err(|e| eprintln!("=== Failed to get -print-multiarch: {e}"))
149+
.ok()
150+
})
151+
.and_then(|output| String::from_utf8(output.stdout).ok())
152+
.map_or_else(
153+
|| {
154+
eprintln!("=== Failed to get DEB_TARGET_MULTIARCH, trying common multiarch paths");
155+
vec![
156+
"x86_64-linux-gnu".to_string(),
157+
"aarch64-linux-gnu".to_string(),
158+
"arm-linux-gnueabihf".to_string(),
159+
]
160+
},
161+
|multiarch| vec![multiarch.trim().to_string()],
162+
)
163+
};
132164

133165
eprintln!("=== Trying multiarch paths: {try_multiarch:?}");
134166

0 commit comments

Comments
 (0)