How to use compiled rust library file(.rlib file)

guys i am new to rust and i am writing my own personal set of math library to make job easy , have lot of work that requires me to play with math (kind of lazy shortcuts, i used to have them in C as well )

i want to make use of compiled library (that single .rlib file) , because i have to share it with my friends (and i don't want distribute it in source form , because they will try being cool and mess up the project at their end and i will have to waste days finding the issue )

1 Like

Rust's rlib does not have a stable ABI, so generally it isn't used by anyone outside of Rust compiler's own internals.

The Rust ecosystem generally does not use rustc directly, and doesn't micromanage builds in the style of Makefile/CMake/Meson/Bazel. Instead of building things manually and fiddling with the intermediate build products, almost everyone uses Cargo, which handles everything itself, from downloading packages for dependencies, to building, linking, documentation generation, and testing and benchmarking.

It's all done automatically for you based on Cargo.toml metadata and crates.io downloads. The intermediate build products and caches all hidden from view. You never touch any rlib files, you never gather prebuilt libraries manually. In most cases you don't need to have any build scripts at all, and no configuration other than package name and minimum version specified in the [dependencies] table in Cargo.toml.


However, if you really really insist on using a precompiled Rust library, then the process for this is much more difficult and very very tedious. The rlib files are unsuitable for distribution (they depend on precise compiler version and settings), so you need to do it all the hard way:

  1. First, you need to design and implement a C-compatible interface for your library, because an rlib with a native Rust interface may not work anywhere outside of your own machine. There's a crate that helps, but it's still a lot of work to change the public interface.
  2. Make your library project a Cargo project that builds a cdylib crate-type (that gives you .so/.dylib/.dll).
  3. Create your own build pipeline that builds the library, sets correct rpath for it (cargo-c helps), and find an alternative distribution method (like a Linux distro package or an MSI installer). Cargo doesn't support this workflow, so you need some other build tool on top of it. crates.io is not supposed to be used for pre-built dynamic libraries, so find another host.
  4. Then write a second crate, a sys crate that finds your prebuilt already-installed .so/.dylib/.dll library on the system, and emits appropriate linking commands for Cargo. You may also want it to recreate a higher-level safe Rust API that has been lost in the step 1 due to limitations of the C ABI.
  5. Instruct your users to download your package/installer, install the library on the system first (Cargo is not supposed to do that), and then they should use the -sys crate to integrate the library with their project. This will make the combined project have two or more copies of Rust's standard library. There's no way to avoid that currently.

So as you can see, moving away from Cargo's preferred method of building static libraries from source is a massive PITA. The requirement to use precompiled libraries changes Cargo from an easy dependency management tool, to something completely unsuitable for the job, and you have to fight on every step of the way. And because everyone else uses Cargo, not having compatibility with Cargo makes your library unusable to most Rust users.

So try to do anything else other than rlib, or any other precompiled library type. Less painful ways of using a Rust library in other Rust projects:

  • if it's just in your project, use workspaces. In Cargo.toml add [dependencies] your_helper = { path="../your_helper" } to a path of another Cargo project, and it will make it automatically built and available to use (if there's ../your_helper/Cargo.toml for the dependency).

  • if you want to share it just between friends or colleagues, use git: In Cargo.toml add [dependencies] your_helper = { git = "https://github.com/your/helper" }. It expects a repository with source code and a Cargo.toml for it.

  • if you want to share it with everyone, publish it on crates.io in source code form: cargo publish. Again it has to be a project with a Cargo.toml and source code available. There is no support for binary libraries.

These methods expose the source code to everyone who access the dependency, but for git dependencies and crates.io packages the access can be read-only and you control who can modify the code.

5 Likes

Rlibs also expose a decent amount of information that may allow deriving the source code in their crate metadata. The crate metadata contains source locations, declarations for all items, including private items and MIR for generic and #[inline] functions. It also contains all doc comments and most other attributes.

1 Like