Skip to content

Commit

Permalink
Update 'replace_needed' to reduce total calls to 'patchelf'
Browse files Browse the repository at this point in the history
  • Loading branch information
messense committed May 8, 2022
1 parent 0b4231b commit 252297f
Show file tree
Hide file tree
Showing 2 changed files with 19 additions and 9 deletions.
13 changes: 6 additions & 7 deletions src/auditwheel/patchelf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,15 @@ use std::path::Path;
use std::process::Command;

/// Replace a declared dependency on a dynamic library with another one (`DT_NEEDED`)
pub fn replace_needed<S: AsRef<OsStr>>(
pub fn replace_needed<O: AsRef<OsStr>, N: AsRef<OsStr>>(
file: impl AsRef<Path>,
old_lib: &str,
new_lib: &S,
old_new_pairs: &[(O, N)],
) -> Result<()> {
let mut cmd = Command::new("patchelf");
cmd.arg("--replace-needed")
.arg(old_lib)
.arg(new_lib)
.arg(file.as_ref());
for (old, new) in old_new_pairs {
cmd.arg("--replace-needed").arg(old).arg(new);
}
cmd.arg(file.as_ref());
let output = cmd
.output()
.context("Failed to execute 'patchelf', did you install it? Hint: Try `pip install maturin[patchelf]` (or just `pip install patchelf`)")?;
Expand Down
15 changes: 13 additions & 2 deletions src/build_context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,23 +309,34 @@ impl BuildContext {
if !lib.rpath.is_empty() || !lib.runpath.is_empty() {
patchelf::set_rpath(&dest_path, &libs_dir)?;
}
patchelf::replace_needed(artifact, &lib.name, &new_soname)?;
soname_map.insert(
lib.name.clone(),
(new_soname.clone(), dest_path.clone(), lib.needed.clone()),
);
}

let replacements = soname_map
.iter()
.map(|(k, v)| (k, v.0.clone()))
.collect::<Vec<_>>();
if !replacements.is_empty() {
patchelf::replace_needed(artifact, &replacements[..])?;
}

// we grafted in a bunch of libraries and modified their sonames, but
// they may have internal dependencies (DT_NEEDED) on one another, so
// we need to update those records so each now knows about the new
// name of the other.
for (new_soname, path, needed) in soname_map.values() {
let mut replacements = Vec::new();
for n in needed {
if soname_map.contains_key(n) {
patchelf::replace_needed(path, n, &soname_map[n].0)?;
replacements.push((n, soname_map[n].0.clone()));
}
}
if !replacements.is_empty() {
patchelf::replace_needed(artifact, &replacements[..])?;
}
writer.add_file_with_permissions(libs_dir.join(new_soname), path, 0o755)?;
}

Expand Down

0 comments on commit 252297f

Please sign in to comment.