rsfindlibs

Crates.iorsfindlibs
lib.rsrsfindlibs
version0.1.1
sourcesrc
created_at2024-11-20 14:44:39.507853
updated_at2024-11-22 11:33:40.854387
descriptionFind shared libraries in the system and provide a useful macro to load them.
homepage
repositoryhttps://gitub.com/ecmwf/rsfindlibs
max_upload_size
id1454843
size24,659
Tom (TomHodson)

documentation

README

📦 RSFindLibs: Rust Dynamic Library Finder & Wrapper Generator

A handy Rust library for:

  1. 🔍 Finding dynamic libraries at runtime.
  2. 🛠️ Generates the boilerplate needed by libloading

🔍 Library Finder

The find function helps you locate a dynamic library (.so, .dylib, .dll) at runtime by searching in:

  • 🏗️ System paths
  • ⚙️ Environment-specific paths (e.g., $CONDA_PREFIX, LD_LIBRARY_PATH)
  • 🔧 Custom-configured directories

Example

let libpath = rsfindlibs::find("fdb5", None).expect("Library not found");
println!("Library found at: {}", libpath);

There is also a handy command line tool that let's you see where rsfindlibs is looking:

➜ cargo run fdb5 -v
Starting search for library 'fdb5' package = 'None'
Chose library extension '.dylib' for OS 'macos'
Adding these current executable directories to search roots:
  /Users/user/git/rust/rsfindlibs/target/debug
Detected Conda environment:
  /Users/user/micromamba/envs/ionbeam
Found environment variable 'fdb5_home'.
  fdb5_home
Found LD_LIBRARY_PATH
  test/libfdb5.dylib
Checking common system paths:
   /
   /usr/
   /usr/local/
   /opt/
   /opt/homebrew/
Searching roots in order:
  ❌  /Users/user/git/rust/rsfindlibs/target/debug/lib/libfdb5.dylib
  ❌  /Users/user/git/rust/rsfindlibs/target/debug/lib64/libfdb5.dylib
  ✅  /Users/user/micromamba/envs/a_conda_env/lib/libfdb5.dylib
  ❌  /Users/user/micromamba/envs/a_conda_env/lib64/libfdb5.dylib
  ❌  fdb5_home/lib/libfdb5.dylib
  ❌  fdb5_home/lib64/libfdb5.dylib
  ❌  test/libfdb5.dylib/lib/libfdb5.dylib
  ❌  test/libfdb5.dylib/lib64/libfdb5.dylib
  ❌  /lib/libfdb5.dylib
  ❌  /lib64/libfdb5.dylib
  ❌  /usr/lib/libfdb5.dylib
  ❌  /usr/lib64/libfdb5.dylib
  ❌  /usr/local/lib/libfdb5.dylib
  ❌  /usr/local/lib64/libfdb5.dylib
  ❌  /opt/lib/libfdb5.dylib
  ❌  /opt/lib64/libfdb5.dylib
  ❌  /opt/homebrew/lib/libfdb5.dylib
  ❌  /opt/homebrew/lib64/libfdb5.dylib
Library found: /Users/user/micromamba/envs/a_conda_env/lib/libfdb5.dylib

🛠️ Macro for Generating Wrappers

The generate_library_wrapper! macro simplifies working with dynamic libraries by generating structs to load and call their functions seamlessly.

How It Works

  1. Declare the library functions you want to use.
  2. The macro generates a wrapper struct that loads the library and makes functions accessible like native Rust functions.

Example

use rsfindlibs::generate_library_wrapper;
use libloading::Library;

generate_library_wrapper! {
    FdbApiWrapper {
        fn fdb_new_handle(fdb: *mut *mut FdbHandle) -> c_int;
        fn fdb_initialise() -> c_int;
        fn fdb_flush(fdb: *mut FdbHandle) -> c_int;
    }
}

pub static FDBLIB: Lazy<Arc<FdbApiWrapper>> = Lazy::new(|| {
    let libpath = rsfindlibs::find("fdb5", None).expect("FDB5 library not found");
    let raw_lib = Library::new(&libpath).expect("Failed to load library");
    let fdblib_wrapper = FdbApiWrapper::load(raw_lib).map_err(|e| e.to_string()).expect("Failed to wrap FDB5 library");
    Arc::new(fdblib_wrapper)
});

🚀 Installation

Add the following to your Cargo.toml:

[dependencies]
rsfindlibs = "0.1"

📄 License

Apache 2.0

Commit count: 0

cargo fmt