Skip to content

Commit 37fe7cf

Browse files
fahdfadyviferga
andauthored
rust metacall-sys crate: enhance searching with RPATH handling for C Libs discovery across platforms (binary) and improve metacall-sys cargo (#576)
* feat(rs metacall-sys): enhance searching with RPATH handling for library discovery across platforms (binary) * Update Cargo.toml * Update Cargo.toml * Update lib.rs --------- Co-authored-by: Vicente Eduardo Ferrer Garcia <7854099+viferga@users.noreply.github.com>
1 parent 5188400 commit 37fe7cf

File tree

2 files changed

+52
-2
lines changed

2 files changed

+52
-2
lines changed
Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
11
[package]
22
name = "metacall-sys"
3-
version = "0.1.0"
4-
repository = "https://github.com/metacall/core/tree/develop/source/ports/rs_port"
3+
version = "0.1.1"
4+
repository = "https://github.com/metacall/core/tree/develop/source/ports/rs_port/sys"
5+
keywords = ["ffi", "bindings", "metacall"]
56
edition = "2021"
67
license = "Apache-2.0"
78
description = "Crate for finding metacall library in the system."
9+
10+
[lib]
11+
crate-type = ["lib"]
12+
doctest = false
13+
edition = "2021"
14+
name = "metacall_sys"
15+
path = "src/lib.rs"

source/ports/rs_port/sys/src/lib.rs

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,45 @@ fn define_library_search_path(env_var: &str, separator: &str, path: &Path) -> St
188188
format!("{}={}", env_var, combined)
189189
}
190190

191+
/// Set RPATH for runtime library discovery
192+
/// This binaries work outside cargo
193+
fn set_rpath(lib_path: &Path) {
194+
let path_str = lib_path.to_str().unwrap();
195+
196+
#[cfg(target_os = "linux")]
197+
{
198+
// On Linux, use RPATH with $ORIGIN for relocatable binaries
199+
println!("cargo:rustc-link-arg=-Wl,-rpath,{}", path_str);
200+
// Also set a backup rpath relative to the executable location
201+
println!("cargo:rustc-link-arg=-Wl,-rpath,$ORIGIN");
202+
println!("cargo:rustc-link-arg=-Wl,-rpath,$ORIGIN/../lib");
203+
}
204+
205+
#[cfg(target_os = "macos")]
206+
{
207+
// On macOS, use @rpath and @loader_path
208+
println!("cargo:rustc-link-arg=-Wl,-rpath,{}", path_str);
209+
// Also set loader-relative paths for relocatable binaries
210+
println!("cargo:rustc-link-arg=-Wl,-rpath,@loader_path");
211+
println!("cargo:rustc-link-arg=-Wl,-rpath,@loader_path/../lib");
212+
}
213+
214+
#[cfg(target_os = "aix")]
215+
{
216+
// Add default system library paths to avoid breaking standard lookup
217+
println!("cargo:rustc-link-arg=-Wl,-blibpath:{}:/usr/lib:/lib", path_str);
218+
}
219+
220+
#[cfg(target_os = "windows")]
221+
{
222+
// Windows doesn't use RPATH, but we can inform the user
223+
println!(
224+
"cargo:warning=On Windows, make sure {} is in your PATH or next to your executable",
225+
path_str
226+
);
227+
}
228+
}
229+
191230
pub fn build() {
192231
// When running tests from CMake
193232
if let Ok(val) = env::var("PROJECT_OUTPUT_DIR") {
@@ -216,6 +255,9 @@ pub fn build() {
216255
println!("cargo:rustc-link-search=native={}", lib_path.path.display());
217256
println!("cargo:rustc-link-lib=dylib={}", lib_path.library);
218257

258+
// Set RPATH so the binary can find libraries at runtime
259+
set_rpath(&lib_path.path);
260+
219261
// Set the runtime environment variable for finding the library during tests
220262
#[cfg(target_os = "linux")]
221263
const ENV_VAR: &str = "LD_LIBRARY_PATH";

0 commit comments

Comments
 (0)