Course contentsShow
← Rust
Lesson 1484 of 1,91012. Unsafe Rust and Low-Level AccessFree lesson

Managing Library Search Paths

You will configure rpaths and search directories to resolve library dependencies reliably.

In this lesson, you will learn how to precisely control where the linker locates dynamic libraries at both build time and runtime using rpath.

The Problem with Dynamic Linking

When your Rust program links against an external C library dynamically, the linker needs to resolve dependencies during two distinct phases. At build time, it searches for the library to satisfy symbols. At runtime, the operating system's dynamic loader searches for the library again to load it into memory. If the library resides in a non-standard location (like a project-specific /lib folder), the loader will fail unless you explicitly tell it where to look.

Configuring RPaths

To ensure your executable "remembers" where to find its dependencies, we use rpath (Run-path). This embeds a hardcoded directory path directly into the ELF or Mach-O binary.

In your build.rs script, you can instruct the linker to set the rpath using the cargo:rustc-link-arg instruction. For Linux, you typically pass the -Wl,-rpath flag:

// In build.rs
fn main() {
    let lib_path = "/path/to/your/custom/libs";
    
    // Tell the linker to link against the library
    println!("cargo:rustc-link-search=native={}", lib_path);
    
    // Embed the RPath into the executable for runtime lookup
    println!("cargo:rustc-link-arg=-Wl,-rpath={}", lib_path);
}

Using $ORIGIN for Portability

Hardcoding absolute paths is often brittle. A more robust approach is to use the $ORIGIN token (on Linux) or @loader_path (on macOS). This tells the loader to search relative to the location of the executable itself:

println!("cargo:rustc-link-arg=-Wl,-rpath,$ORIGIN/../lib");

By setting this, you can move your application folder anywhere on the system, and the dynamic loader will successfully locate your dependencies as long as the relative structure remains intact. This approach avoids the need to globally modify the LD_LIBRARY_PATH environment variable, keeping your deployment clean and self-contained.

Key Takeaway: Use RPaths embedded via rustc-link-arg and the $ORIGIN variable to ensure your application can reliably locate its dynamic dependencies without relying on global system environment variables.