Call functions from a relative path lib.so/dll

(The following answer is for unix)

This is about the way a binary that depends on a dynamic library looks for it when run. You can see it with $ ldd ./the-binary.

Now, where does the binary look for the dynamic libraries? You can find all the information in the man page of ld.so.

Long story short, when running_ the binary, the dynamic libraries are searched for in directories:

  1. specified by the -rpath=... flag given, beforehand, to the linker when "compiling",

  2. then in the LD_LIBRARY_PATH environment variable,

  3. then in some places specified by some files in /etc/ld_preload...,

  4. and then in /lib and /usr/lib.

The -L linker parameter is of no use (it's just a sanity check, quite surprising to be honest).

Since you have specified the -C rpath flag to rustc in the Cargo.toml file, I guess it must be the reason it worked in the deps folder. The reason it works with cargo run is that cargo sets the LD_LIBRARY_PATH to include the deps folder.

But more generally, you need to add the -C link-args=-Wl,-rpath=PATH_TO_LIB_HERE to the rust flags, either with the RUSTFLAGS env var, or within the .cargo/config file:

  • absolute path;

    • RUSTFLAGS="-L src/vendor -C link-args=-Wl,-rpath=$PWD/src/vendor/"
  • relative path (not recommended, since it is relative to the calling site, not to the binary location);

    • RUSTFLAGS="-L src/vendor -C link-args=-Wl,-rpath=./src/vendor/"
  • relative to the binary location with the $ORIGIN meta-variable.

    • RUSTFLAGS='-L src/vendor -C link-args=-Wl,-rpath=$ORIGIN/../../src/vendor' (note the single quotes: $ORIGIN is not an env var but text which needs to be passed verbatim).

So, for instance, you could try to set the rpath to $ORIGIN/ to make it work when the binary and the library are in the same dir.


Aside

Your extern declaration is wrong: you should use ::libc::c_int instead of i8 to represent C's integer type:

use ::libc::c_int;

#[link(name = "add")]
extern "C" {
    fn add (a: c_int, b: c_int) -> c_int;
}
3 Likes