Skip to content

Commit

Permalink
Merge pull request #905 from messense/replace-needed
Browse files Browse the repository at this point in the history
Update 'replace_needed' to reduce total calls to 'patchelf'
  • Loading branch information
messense authored May 8, 2022
2 parents 0b4231b + 3ecdb6a commit 5bba431
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 11 deletions.
1 change: 1 addition & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

* Add Linux armv7l python sysconfig in [#901](https://github.com/PyO3/maturin/pull/901)
* Add NetBSD python sysconfig in [#903](https://github.com/PyO3/maturin/pull/903)
* Update 'replace_needed' to reduce total calls to 'patchelf' in [#905](https://github.com/PyO3/maturin/pull/905)

## [0.12.15] - 2022-05-07

Expand Down
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(path, &replacements[..])?;
}
writer.add_file_with_permissions(libs_dir.join(new_soname), path, 0o755)?;
}

Expand Down
4 changes: 3 additions & 1 deletion tests/manylinux_compliant.sh
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
#!/bin/bash
set -e

which cargo > /dev/null 2>&1 || curl -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal

for PYBIN in /opt/python/cp3[6789]*/bin; do
for PYBIN in /opt/python/cp3[789]*/bin; do
cargo run -- build --no-sdist -m test-crates/pyo3-mixed/Cargo.toml -i "${PYBIN}/python" --manylinux $1 -o dist
done
5 changes: 4 additions & 1 deletion tests/manylinux_incompliant.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
#!/bin/bash
set -e

which cargo > /dev/null || curl -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal

# Fail because we're running in manylinux2014, which can't build for manylinux 2010
Expand All @@ -12,7 +14,8 @@ for PYBIN in /opt/python/cp3[9]*/bin; do
done

# Fail because we're linking zlib with black-listed symbols(gzflags), which is not allowed in manylinux
yum install -y zlib-devel
apt-get -v &> /dev/null && apt-get install -y zlib1g-dev || yum install -y zlib-devel

for PYBIN in /opt/python/cp3[9]*/bin; do
if cargo run -- build --no-sdist -m test-crates/lib_with_disallowed_lib/Cargo.toml -i "${PYBIN}/python" --manylinux 2014 -o dist; then
echo "maturin build unexpectedly succeeded"
Expand Down

0 comments on commit 5bba431

Please sign in to comment.