Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Creating and linking static rust library and link to c

I tried to create a rust library that is callable by a c program, so far i managed to create a dynamic library and call it (library created using rustc --crate-type=cdylib src/lib.rs -o libCustomlib.so, linked using gcc main.o -lCustomlib).

When i now take the same code but compile it as a static library (rustc --crate-type=staticlib src/lib.rs -o libCustomlib.a) gcc throws errors when linking (using gcc main.o -L. -l:libCustomlib.a)

the errors are all undefined references to various functions

first few lines:

/usr/bin/ld: ./libCustomlib.a(std-b1b61f01951b016b.std.5rqysbiy-cgu.2.rcgu.o): in function `std::sys::unix::mutex::Mutex::init':
/usr/src/rustc-1.43.0//src/libstd/sys/unix/mutex.rs:46: undefined reference to `pthread_mutexattr_init'
/usr/bin/ld: /usr/src/rustc-1.43.0//src/libstd/sys/unix/mutex.rs:48: undefined reference to `pthread_mutexattr_settype' 
/usr/bin/ld: /usr/src/rustc-1.43.0//src/libstd/sys/unix/mutex.rs:52: undefined reference to `pthread_mutexattr_destroy' 

full error is over 100 lines long but the lines are all of this form

the lib.rs currently only has one test helloWorld function:

#[no_mangle]
pub extern "C" fn fn_test() {
    println!("Hello, world!");
}       

with the header file included in the caller part being:

extern void fn_test();

The question is, is my error at creating the static library or at linking it? Or lies the problem somewhere else and it should not work with static libraries? Should i just use the dynamic approach (which i would like to avoid since static ones feel more like using multiple languages in one exe since you don't have to distribute the library)?

(disclaimer: for everyone asking why i would do something like that without a good reason: it's a fun project, the entire program should be as overcomplicated as possible and that's the reason why i want to use different languages)

like image 249
HED Avatar asked Aug 27 '20 13:08

HED


People also ask

Does Rust statically link?

Rust has supported producing statically linked binaries since RFC #1721 which proposed the target-feature=+crt-static flag to statically link the platform C library into the final binary.

How static library is linked?

Static libraries are either merged with other static libraries and object files during building/linking to form a single executable or loaded at run-time into the address space of their corresponding executable at a static memory offset determined at compile-time/link-time.

Does Rust use dynamic linking?

To be extra clear about this, Rust does support dynamic linking; it's just limited to interfacing via the stable C ABI.


Video Answer


1 Answers

On Linux, std dynamically links to pthreads and libdl. You need to link these in as well to create the executable:

gcc main.o libCustomlib.a -lpthread -ldl

The result is a binary that links dynamically to a handful of fundamental libraries, but statically to Customlib.

If you want a purely statically linked binary, you will probably need to use no_std and enable only the specific features of core that do not depend on dynamically linked system libraries. (Certain libraries cannot be statically linked on Linux; read Statically linking system libraries, libc, pthreads, to aid in debugging) Just for a toy program like hello, world you may get away with simply passing -static to gcc, but for anything robust it's better to dynamically link these fundamental libraries.

like image 153
trent Avatar answered Sep 30 '22 13:09

trent