Skip to content

Commit 2304e15

Browse files
committed
Enhance rpath handling in fdb build scripts
1 parent 12e4e60 commit 2304e15

File tree

2 files changed

+44
-1
lines changed

2 files changed

+44
-1
lines changed

rust/crates/fdb-sys/build.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,13 +67,25 @@ fn build_system() {
6767
.expect("DEP_ECKIT_ROOT not set - eckit-sys must be a dependency");
6868
let metkit_root = env::var("DEP_METKIT_ROOT")
6969
.expect("DEP_METKIT_ROOT not set - metkit-sys must be a dependency");
70+
let eccodes_root = env::var("DEP_ECCODES_ROOT")
71+
.expect("DEP_ECCODES_ROOT not set - eccodes-sys must be a dependency");
7072

7173
println!("cargo:rustc-link-search=native={eckit_root}/lib");
7274
println!("cargo:rustc-link-lib=dylib=eckit");
7375
println!("cargo:rustc-link-search=native={metkit_root}/lib");
7476
println!("cargo:rustc-link-lib=dylib=metkit");
7577
bindman_utils::link_cpp_stdlib();
7678

79+
// Re-publish each dependency's install lib dir so the downstream
80+
// `fdb` crate's build script can emit matching absolute rpath
81+
// entries on the final binary. `rustc-link-arg` emitted by a
82+
// library crate's build.rs does not reach binaries that link the
83+
// crate, so the rpath flags have to come from `fdb/build.rs`.
84+
println!("cargo:system_fdb5_lib={}", lib_dir.display());
85+
println!("cargo:system_eckit_lib={eckit_root}/lib");
86+
println!("cargo:system_metkit_lib={metkit_root}/lib");
87+
println!("cargo:system_eccodes_lib={eccodes_root}/lib");
88+
7789
// Export for downstream crates
7890
println!("cargo:root={}", root.display());
7991
println!("cargo:include={}", fdb_include.display());

rust/crates/fdb/build.rs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,39 @@
22
//!
33
//! Emits RPATH linker flags so binaries can find dynamic libraries
44
//! at runtime without setting `LD_LIBRARY_PATH`/`DYLD_LIBRARY_PATH`.
5-
5+
//!
6+
//! Two layouts are supported:
7+
//!
8+
//! - **Vendored** (default): dynamic libs are copied into
9+
//! `fdb_libs/` and `eccodes_libs/` subdirectories next to the
10+
//! final binary. The rpath entries are binary-relative
11+
//! (`@executable_path/fdb_libs` on macOS, `$ORIGIN/fdb_libs` on
12+
//! Linux), so the binary is portable as long as the user ships
13+
//! those two directories alongside it.
14+
//!
15+
//! - **System**: libraries live wherever `find_package` resolved
16+
//! them (e.g. `/usr/lib`, `/opt/.../lib`, or a custom prefix).
17+
//! `fdb-sys`'s build script re-publishes each dependency's lib dir
18+
//! via `cargo:system_*_lib` metadata keys, and we emit an
19+
//! absolute rpath entry for each one so the binary still loads
20+
//! without `LD_LIBRARY_PATH` / `DYLD_LIBRARY_PATH`.
621
fn main() {
722
println!("cargo:rerun-if-changed=build.rs");
823
bindman_utils::emit_rpath_flags(&["fdb_libs", "eccodes_libs"]);
24+
25+
// When fdb-sys is in system mode, it re-publishes each
26+
// dependency's install lib dir so we can stamp matching
27+
// absolute rpath entries onto the final binary. The vendored
28+
// build leaves these unset, so this block is a no-op there.
29+
for key in [
30+
"DEP_FDB_SYS_SYSTEM_FDB5_LIB",
31+
"DEP_FDB_SYS_SYSTEM_ECKIT_LIB",
32+
"DEP_FDB_SYS_SYSTEM_METKIT_LIB",
33+
"DEP_FDB_SYS_SYSTEM_ECCODES_LIB",
34+
] {
35+
println!("cargo:rerun-if-env-changed={key}");
36+
if let Ok(lib_dir) = std::env::var(key) {
37+
println!("cargo:rustc-link-arg=-Wl,-rpath,{lib_dir}");
38+
}
39+
}
940
}

0 commit comments

Comments
 (0)