Skip to content

Commit 7f97efe

Browse files
committed
Add support for repairing cross compiled linux wheels
1 parent 9295d8f commit 7f97efe

File tree

4 files changed

+51
-3
lines changed

4 files changed

+51
-3
lines changed

Cargo.lock

Lines changed: 1 addition & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ dialoguer = "0.9.0"
5858
console = "0.15.0"
5959
minijinja = "0.8.2"
6060
lddtree = "0.2.0"
61+
cc = "1.0.72"
6162

6263
[dev-dependencies]
6364
indoc = "1.0.3"

src/auditwheel/repair.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,9 @@ use std::path::{Path, PathBuf};
1010
pub fn get_external_libs(
1111
artifact: impl AsRef<Path>,
1212
policy: &Policy,
13+
sysroot: PathBuf,
1314
) -> Result<Vec<lddtree::Library>, AuditWheelError> {
14-
let root = PathBuf::from("/");
15-
let dep_analyzer = DependencyAnalyzer::new(root);
15+
let dep_analyzer = DependencyAnalyzer::new(sysroot);
1616
let deps = dep_analyzer.analyze(artifact).unwrap();
1717
let mut ext_libs = Vec::new();
1818
for (name, lib) in deps.libraries {

src/build_context.rs

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use lddtree::Library;
1515
use std::borrow::Cow;
1616
use std::collections::HashMap;
1717
use std::path::{Path, PathBuf};
18+
use std::process::{Command, Stdio};
1819

1920
/// The way the rust code is used in the wheel
2021
#[derive(Clone, Debug, PartialEq, Eq)]
@@ -272,7 +273,8 @@ impl BuildContext {
272273
}
273274
})?;
274275
let external_libs = if should_repair && !self.editable {
275-
get_external_libs(&artifact, &policy).with_context(|| {
276+
let sysroot = get_sysroot_path(&self.target)?;
277+
get_external_libs(&artifact, &policy, sysroot).with_context(|| {
276278
if let Some(platform_tag) = platform_tag {
277279
format!("Error repairing wheel for {} compliance", platform_tag)
278280
} else {
@@ -685,6 +687,50 @@ fn relpath(to: &Path, from: &Path) -> PathBuf {
685687
result
686688
}
687689

690+
/// Get sysroot path from target C compiler
691+
///
692+
/// Currently only gcc is supported, clang doesn't have a `--print-sysroot` option
693+
/// TODO: allow specify sysroot from environment variable?
694+
fn get_sysroot_path(target: &Target) -> Result<PathBuf> {
695+
use crate::target::get_host_target;
696+
697+
let host_triple = get_host_target()?;
698+
let target_triple = target.target_triple();
699+
if host_triple != target_triple {
700+
let mut build = cc::Build::new();
701+
build
702+
// Suppress cargo metadata for example env vars printing
703+
.cargo_metadata(false)
704+
// opt_level, host and target are required
705+
.opt_level(0)
706+
.host(&host_triple)
707+
.target(target_triple);
708+
let compiler = build
709+
.try_get_compiler()
710+
.with_context(|| format!("Failed to get compiler for {}", target_triple))?;
711+
let path = compiler.path();
712+
let out = Command::new(path)
713+
.arg("--print-sysroot")
714+
.stdout(Stdio::piped())
715+
.stderr(Stdio::null())
716+
.output()
717+
.with_context(|| format!("Failed to run `{} --print-sysroot`", path.display()))?;
718+
if out.status.success() {
719+
let sysroot = String::from_utf8(out.stdout)
720+
.context("Failed to read the sysroot path")?
721+
.trim()
722+
.to_owned();
723+
return Ok(PathBuf::from(sysroot));
724+
} else {
725+
bail!(
726+
"Failed to get the sysroot path: {}",
727+
String::from_utf8(out.stderr)?
728+
);
729+
}
730+
}
731+
Ok(PathBuf::from("/"))
732+
}
733+
688734
#[cfg(test)]
689735
mod test {
690736
use super::relpath;

0 commit comments

Comments
 (0)