Where should I place a static library so I can link it with a Rust program?

Where should I place a static library

Wherever you want. You have to tell the compiler where to find it.


First, let's create a static library

$ cat hello.c
int square(int value) {
  return value * value;
}
$ gcc -c -o hello.o hello.c
$ ar rcs libhello.a hello.o

Next, we use a build script to set the value of rustc-link-search to point to the directory where I put the library:

fn main() {
    println!("cargo:rustc-link-search=/Projects/stack-overflow/using-c-static/");
}

We can now use the functions from the library:

#[link(name = "hello")]
extern "C" {
    fn square(val: i32) -> i32;
}

fn main() {
    let r = unsafe { square(3) };
    println!("3 squared is {}", r);
}

That's the basic functionality. You could also use the build script to specify which library to link, instead of having it in your code (rustc-link-lib). I prefer this because then the two configurations are right next to each other.

You should also probably follow the *-sys naming convention and create a crate dedicated to exposing the underlying API. Importantly, this crate should specify the link manifest key to avoid duplicate symbols at linking time.

If your build script needs more information, cargo passes many parameters via environment variables.

If you are compiling C code as part of your crate, you should look into crates like cc or cmake, which make the act of building a piece of software much easier.


I just found a solution (two) but I do not know if it's the best way:

1- way

build.rs file

extern crate gcc;

fn main() {

    println!("cargo:rustc-link-search=native=/home/path/to/rust/proyect/folder/contain/file.a");
    println!("cargo:rustc-link-lib=static=test");
}

Cargo.toml

//..
build = "build.rs"
//..

2- way

Cargo.toml

//..
rustc-link-search = ["./src/lib"]
rustc-link-lib = ["test"]
root = "/home/path/to/rust/proyect/"
//..

["./src/lib"] -> place to lib.a refence to root

Tags:

Rust