What's the best way to compile a crate into a single lib file that's linkable by rustc?

I have a crate called mylib, which has a lot of dependancies. I'm looking for a way to include this library as a single file, and able to be linked with rustc, hopefully something like this (pseudo command):

rustc main.rs -l mylib.lib

I'm trying rlib. I copied to .rlib file generated by cargo and ran this:

rustc main.rs --extern lib=mylib.rlib

However, it couldn't find all the dependancies of mylib

error[E0463]: can't find crate for `rayon` which `mylib` depends on

Is there a way to make .rlib file contain all the dependancies' data? (the .rlib file is bigger than the binary compiled by cargo so I assume the code is already packed?) If not what's the best way to compile a crate into a single lib file?

No, it does contain metadata and llvm bitcode for lto though.

Why dont you want just use cargo?

2 Likes

Perhaps you could compile the crate as a staticlib and then link to that.

I believe that error will be fixed when you pass -L/path/to/rlib/dir

Using staticlib will only work when you only want to use c ffi. Staticlibs dont contain the necessary metadata to use as rust library.

1 Like

It does work if I pass the whole mylib/target/debug/deps to -L, but my goal is to not have to pass these and pack the whole library into a single file, is such thing impossible?

Also running with rustc

rustc main.rs --extern mylib=mylib/target/debug/libmylib.rlib -L mylib/target/debug/deps
// main.rs
fn main() {
    mylib::hello();
}

works but

use mylib::*;

fn main() {
    hello();
}

says unresolved import "mylib"

No, the .rlib file only contains code for a single crate, not its dependencies. (It's probably bigger than the final binary because of serialized metadata and other things it contains alongside the object code.)

If you've used C or C++ before, you can think of an .rlib as similar to a .o file. There isn't really a Rust equivalent to a static library (.a or .lib file).

You can fix this by passing --edition=2018 to rustc, or by adding extern crate mylib; to main.rs so that it works in the 2015 edition.

1 Like

Thanks that's really clear! So there's no way to pack a complete rust library with deps to a single file that's importable by rustc right?

Try looking at the linkage explained here in the rust reference. Maybe what you're looking for is the staticlib type of linkage?

I've checked this page. I'm looking for something like .a staticlib, but for rust (can be directly linked and use as a crate via rustc) instead of linking to non-rust applications.