diff --git a/Changelog.md b/Changelog.md index e8d232194..4512661d7 100644 --- a/Changelog.md +++ b/Changelog.md @@ -14,6 +14,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Add `zig ar` support in [#1073](https://github.com/PyO3/maturin/pull/1073) * Fix sdist build for optional path dependencies in [#1084](https://github.com/PyO3/maturin/pull/1084) * auditwheel: find dylibs in Cargo target directory in [#1092](https://github.com/PyO3/maturin/pull/1092) +* Add library search paths in Cargo target directory to rpath in editable mode on Linux in [#1094](https://github.com/PyO3/maturin/pull/1094) ## [0.13.2] - 2022-08-14 diff --git a/src/auditwheel/audit.rs b/src/auditwheel/audit.rs index 50001e976..bca9571c3 100644 --- a/src/auditwheel/audit.rs +++ b/src/auditwheel/audit.rs @@ -429,13 +429,8 @@ pub fn get_policy_and_libs( })?; let external_libs = if should_repair { let sysroot = get_sysroot_path(target).unwrap_or_else(|_| PathBuf::from("/")); - find_external_libs( - &artifact.path, - &policy, - sysroot, - artifact.linked_paths.clone(), - ) - .with_context(|| { + let ld_paths = artifact.linked_paths.iter().map(PathBuf::from).collect(); + find_external_libs(&artifact.path, &policy, sysroot, ld_paths).with_context(|| { if let Some(platform_tag) = platform_tag { format!("Error repairing wheel for {} compliance", platform_tag) } else { diff --git a/src/auditwheel/patchelf.rs b/src/auditwheel/patchelf.rs index 181e40917..c349f63a2 100644 --- a/src/auditwheel/patchelf.rs +++ b/src/auditwheel/patchelf.rs @@ -41,7 +41,7 @@ pub fn set_soname>(file: impl AsRef, soname: &S) -> Result Ok(()) } -/// /// Remove a `RPATH` from executables and libraries +/// Remove a `RPATH` from executables and libraries pub fn remove_rpath(file: impl AsRef) -> Result<()> { let mut cmd = Command::new("patchelf"); cmd.arg("--remove-rpath").arg(file.as_ref()); diff --git a/src/build_context.rs b/src/build_context.rs index b0c7704b2..fcd551b93 100644 --- a/src/build_context.rs +++ b/src/build_context.rs @@ -201,7 +201,7 @@ impl BuildContext { platform_tag: &[PlatformTag], python_interpreter: Option<&PythonInterpreter>, ) -> Result<(Policy, Vec)> { - if self.skip_auditwheel || self.editable { + if self.skip_auditwheel { return Ok((Policy::default(), Vec::new())); } @@ -239,12 +239,43 @@ impl BuildContext { get_policy_and_libs(artifact, tag, &self.target) } + /// Add library search paths in Cargo target directory rpath when building in editable mode + fn add_rpath(&self, artifacts: &[&BuildArtifact]) -> Result<()> { + if self.editable && self.target.is_linux() { + for artifact in artifacts { + if artifact.linked_paths.is_empty() { + continue; + } + let old_rpaths = patchelf::get_rpath(&artifact.path)?; + let mut new_rpaths: Vec<&str> = + old_rpaths.split(':').filter(|r| !r.is_empty()).collect(); + for path in &artifact.linked_paths { + if !old_rpaths.contains(path) { + new_rpaths.push(path); + } + } + let new_rpath = new_rpaths.join(":"); + if let Err(err) = patchelf::set_rpath(&artifact.path, &new_rpath) { + println!( + "⚠️ Warning: Failed to set rpath for {}: {}", + artifact.path.display(), + err + ); + } + } + } + Ok(()) + } + fn add_external_libs( &self, writer: &mut WheelWriter, artifacts: &[&BuildArtifact], ext_libs: &[Vec], ) -> Result<()> { + if self.editable { + return self.add_rpath(artifacts); + } if ext_libs.iter().all(|libs| libs.is_empty()) { return Ok(()); } @@ -343,7 +374,8 @@ impl BuildContext { let old_rpaths = patchelf::get_rpath(&artifact.path)?; // TODO: clean existing rpath entries if it's not pointed to a location within the wheel // See https://github.com/pypa/auditwheel/blob/353c24250d66951d5ac7e60b97471a6da76c123f/src/auditwheel/repair.py#L160 - let mut new_rpaths: Vec<&str> = old_rpaths.split(':').collect(); + let mut new_rpaths: Vec<&str> = + old_rpaths.split(':').filter(|r| !r.is_empty()).collect(); let new_rpath = Path::new("$ORIGIN").join(relpath(&libs_dir, artifact_dir)); new_rpaths.push(new_rpath.to_str().unwrap()); let new_rpath = new_rpaths.join(":"); diff --git a/src/compile.rs b/src/compile.rs index 4bb23d6ce..3b7d64ebc 100644 --- a/src/compile.rs +++ b/src/compile.rs @@ -25,7 +25,7 @@ pub struct BuildArtifact { pub path: PathBuf, /// Array of paths to include in the library search path, as indicated by /// the `cargo:rustc-link-search` instruction. - pub linked_paths: Vec, + pub linked_paths: Vec, } /// Builds the rust crate into a native module (i.e. an .so or .dll) for a @@ -445,9 +445,9 @@ fn compile_target( for path in msg.linked_paths.iter().map(|p| p.as_str()) { // `linked_paths` may include a "KIND=" prefix in the string where KIND is the library kind if let Some(index) = path.find('=') { - linked_paths.push(PathBuf::from(&path[index + 1..])); + linked_paths.push(path[index + 1..].to_string()); } else { - linked_paths.push(PathBuf::from(path)); + linked_paths.push(path.to_string()); } } } diff --git a/src/module_writer.rs b/src/module_writer.rs index cb6047067..97ac311f1 100644 --- a/src/module_writer.rs +++ b/src/module_writer.rs @@ -1,9 +1,6 @@ //! The wheel format is (mostly) specified in PEP 427 - use crate::project_layout::ProjectLayout; -use crate::PythonInterpreter; -use crate::Target; -use crate::{BridgeModel, Metadata21}; +use crate::{BridgeModel, Metadata21, PythonInterpreter, Target}; use anyhow::{anyhow, bail, Context, Result}; use flate2::write::GzEncoder; use flate2::Compression;