From 16e6cbd4e41a1eab21a78c8ecc881f702ac2c79b Mon Sep 17 00:00:00 2001 From: messense Date: Sun, 8 May 2022 19:18:55 +0800 Subject: [PATCH 1/2] Update 'replace_needed' to reduce total calls to 'patchelf' --- Changelog.md | 1 + src/auditwheel/patchelf.rs | 13 ++++++------- src/build_context.rs | 15 +++++++++++++-- 3 files changed, 20 insertions(+), 9 deletions(-) diff --git a/Changelog.md b/Changelog.md index 7124c8325..36dd7ba3a 100644 --- a/Changelog.md +++ b/Changelog.md @@ -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 diff --git a/src/auditwheel/patchelf.rs b/src/auditwheel/patchelf.rs index f3cd2a1ad..181e40917 100644 --- a/src/auditwheel/patchelf.rs +++ b/src/auditwheel/patchelf.rs @@ -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>( +pub fn replace_needed, N: AsRef>( file: impl AsRef, - 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`)")?; diff --git a/src/build_context.rs b/src/build_context.rs index 73858da53..7cf286850 100644 --- a/src/build_context.rs +++ b/src/build_context.rs @@ -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::>(); + 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)?; } From 3ecdb6ab8932ba620c53937c01f98a57a146d48f Mon Sep 17 00:00:00 2001 From: messense Date: Sun, 8 May 2022 20:01:50 +0800 Subject: [PATCH 2/2] Fix auditwheel manylinux compliance scripts --- tests/manylinux_compliant.sh | 4 +++- tests/manylinux_incompliant.sh | 5 ++++- 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/tests/manylinux_compliant.sh b/tests/manylinux_compliant.sh index 7a4e3b086..5cba08c02 100755 --- a/tests/manylinux_compliant.sh +++ b/tests/manylinux_compliant.sh @@ -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 diff --git a/tests/manylinux_incompliant.sh b/tests/manylinux_incompliant.sh index a04a645c7..e64c9dd4d 100755 --- a/tests/manylinux_incompliant.sh +++ b/tests/manylinux_incompliant.sh @@ -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 @@ -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"