Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I type "cargo run" without needing to set the LD_LIBRARY_PATH shell variable?

Tags:

linux

rust

I build a Rust program that calls a C++ function via a C interface. In order to execute the program, I have to run:

export LD_LIBRARY_PATH=<path to shared c lib>

or I get an error:

error while loading shared libraries: libtest.so: cannot open shared object file: No such file or directory

I tried to set the variable in a build script using std::process::Command

Command::new("sh").arg("export").arg("LD_LIBRARY_PATH=<path to shared c lib>");

Although the command executes without an error, the variable is not set. How can I set the variable from my program while it is being executed?

To be more concrete, I want to type only this:

cargo run

instead of

export LD_LIBRARY_PATH=<path to shared c lib>
cargo run

My code so far:

main.rs

/*---compile all with---
    g++ -c -fpic foo.cpp
    gcc -c -fpic test.c
    g++ -shared foo.o test.o -o libtest.so

    in order to execute we have to set the variable
    export LD_LIBRARY_PATH=/home/jan/Uni/Bachelorarbeit/Programme/Rust_Cpp_crossover_erneut/$LD_LIBARY_PATH

*/
//pub extern crate c_interface;
pub extern crate libc;
use libc::{c_int};



#[link(name = "test")]
extern "C" {
    fn hello_world () -> c_int;
}


fn main() {
    let x;
    unsafe {
        x = hello_world();
    }
    println!("x is: {}", x);
}

test.c

#include "foo.h"

int hello_world () {
    int a = foo();
    return a;
}

foo.cpp

#include <iostream>
#include "foo.h"

using namespace std;

int foo() {
    cout << "Hello, World!" << endl;
    return 0;
}

foo.h

#ifdef __cplusplus
extern "C" {
#endif

int foo();

#ifdef __cplusplus
}
#endif

build.rs

fn main () {
    println!(r"cargo:rustc-link-search=native=/home/jan/Uni/Bachelorarbeit/Programme/Rust_Cpp_crossover_erneut");
}

I have seen How do I specify the linker path in Rust? and it is not a solution to my problem.

like image 569
Mateholiker Avatar asked Oct 17 '22 14:10

Mateholiker


1 Answers

Add the following line to build.rs:

println!("cargo:rustc-env=LD_LIBRARY_PATH=/home/jan/Uni/Bachelorarbeit/Programme/Rust_Cpp_crossover_erneut/");

This only works with cargo run and not with cargo build and then executing the output. The environment variable does not get saved into the binary.

like image 95
Mateholiker Avatar answered Dec 07 '22 14:12

Mateholiker