How to link a dynamic Rust library using only rustc and not cargo?

孤者浪人 提交于 2020-01-06 06:11:48

问题


My main.rs looks like

// #[link(name = "lib")]
extern "C" {
    fn hello();
}

fn main() {
    unsafe {
        hello();
    }
}

And lib.rs:

#[no_mangle]
pub fn hello() {
    println!("Hello, World!");
}

I have compiled lib.rs using rustc --crate-type=cdylib lib.rs -o lib.so

How do I link lib.so to rustc main.rs command ?


回答1:


You need to match ABIs. When you use an extern "C" block, you need to declare your functions using the same ABI.

Name your dynamic library using the platform's conventions. Use .dylib on macOS, .lib on Windows, and .so on Linux. rustc will do this for you automatically if you don't provide a -o option.

Once you have built your dynamic library, you need to add it to the compiler's linker options. rustc --help has a list of the various compiler options. -L adds a directory to the search path and -l links to a specific library.

lib.rs

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

main.rs

extern "C" {
    fn hello();
}

fn main() {
    unsafe {
        hello();
    }
}

Compiled and executed with:

$ rustc --crate-type=cdylib lib.rs
$ rustc main.rs -L . -l lib
$ ./main
Hello, World!

As I'm on macOS, I used otool to show that it's indeed dynamically linked:

$ otool -L main
main:
    liblib.dylib (compatibility version 0.0.0, current version 0.0.0)
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.250.1)
    /usr/lib/libresolv.9.dylib (compatibility version 1.0.0, current version 1.0.0)

See also:

  • Linking Rust application with a dynamic library not in the runtime linker search path
  • How do I specify the linker path in Rust?

For completeness, here's "normal" linking of crates:

lib.rs

pub fn hello() {
    println!("Hello, World!");
}

main.rs

fn main() {
    lib::hello();
}
$ rustc --crate-type=rlib lib.rs
$ rustc main.rs --extern lib=liblib.rlib
$ ./main
Hello, World!
$ otool -L main
main:
    /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 1252.250.1)
    /usr/lib/libresolv.9.dylib (compatibility version 1.0.0, current version 1.0.0)


来源:https://stackoverflow.com/questions/55537573/how-to-link-a-dynamic-rust-library-using-only-rustc-and-not-cargo

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!