#load #find #macro #system #shared #dynamic #generate

bin+lib rsfindlibs

Find shared libraries in the system and provide a useful macro to load them

2 releases

new 0.1.1 Nov 22, 2024
0.1.0 Nov 20, 2024

#58 in #load

Download history 94/week @ 2024-11-15

94 downloads per month

Apache-2.0

12KB
157 lines

📦 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

Dependencies

~4.5–6.5MB
~110K SLoC