How to use a Rust .rlib library in a project

Hello forum !

I have created a Rust .rlib library that has multiple functions I want to use for another some internal Rust projects. I do not need to make it available to the public or to some third parties.

I've read some posts on different forum but it's really not clear to me how to import/use the .rlib library in the other Rust project.

Could anyone give me some hints ?

thanks again and have a nice day !

F

Hello,
what you should:

  1. Open Cargo.toml in your project where you want to link your library.
  2. Link your lib
[dependencies]
my_library = { path = %PATH_TO_YOUR_LIB% }
  1. Use lib in your code
use my_library::my_function;

If you have comipled file .rlib:

  1. Add file in project to folder /libs
  2. Link your lib
[dependencies]
my_library = { path = "libs/my_library" }

3.Use lib
extern crate my_library::my_function;

2 Likes

Generally rlib is not supposed to be used directly, unless you have a strong reason to write your own build system, and lose compatibility with almost every Rust library.

Cargo manages all the library building and linking. Use Cargo.toml to define your libraries and dependencies. Don't call rustc.

5 Likes

I would be surprised if this works. Where did you find this?

there are many similar threads on the forum

Then those threads are wrong, because I just tried this and it doesn't work.

Binary dependencies are, as far as I am aware, not supported. Secondly, extern crate doesn't let you link to a specific path within a library, that code you gave produces a syntax error. Even if I account for that, the compiler still cannot find my_library.

If you have a source for this, you should provide it, because I would also like to know how to do this without directly invoking rustc.

1 Like

I am definitely confused know. I'm new to Rust but used to C.

In such a case I would have created both a mylib.so and mylib.h files and shared them with our team.

I thought that Rust is managing libraries the "same" way. So I have create a Rust library project that has two files:

  • lib.rs with functions to be "exported"
  • type.rs with struct

compiled them and generated mylib.rlib. I hence though to use mylib.rlib inside other Rust projects.

Now it seems that I should:

  1. create a mylib folder inside the Rust project using the library
  2. add both lib.rs and type.rs in the previous folder
  3. Use cargo.toml of the new project to let Rust be aware of the libs files

Is that correct ? If not, how can I achieve a similar result (or which is the better way to do that) ?

thanks

F

Rust at the low level has rustc that is capable of having a similar build model as C, but nobody uses that except for most specialized projects or low-level tooling. You will have a terrible time writing your own build scripts, and being unable to use any of the 150000 Cargo packages in the ecosystem (at least without busywork of redoing what Cargo is doing, manually).

Basically all Rust projects use Cargo.

  • you don't manage any built files manually with Cargo. It's all automated.
  • you don't build nor specify any individual .rlib files with Cargo. It's a hidden implementation detail.
  • you can't directly use any .so files with Cargo. It uses static linking for all of Rust, and there are special wrapper packages for system-wide .so libs.

Run cargo init to create a project and cargo add to add dependencies.

2 Likes

You can use a workspace layout to share code between multiple crates. For example:

/workspace
|- Cargo.toml
|- /lib-a
|  |- Cargo.toml
|  +- /src
|- /lib-b
|  |- Cargo.toml
|  +- /src
+- /bin-c
   |- Cargo.toml
   +- /src

/workspace/Cargo.toml specifies the Cargo workspace. lib-a and lib-b are just normal Cargo library crates. bin-c can use those by specifying them as dependencies like so:

# /bin-c/Cargo.toml
[dependencies]
lib-a = { path = "../lib-a" }
lib-b = { path = "../lib-b" }

These crates don't need to be published anywhere. Note that this is all using source code; precompiled .rlibs don't really fit in anywhere here.

1 Like

There's little-to-no support for distributing pre-compiled Rust libraries in the Rust ecosystem. Rust also does not, that I know of, guarantee that rlib files will remain compatible between Rust versions, even on the same target triple. Almost all library distribution is in source form, via Cargo, as a result.

There are a couple of ways to distribute "internal" libraries for Cargo, which should not be published to crates.io or made available to the public. The most straightforwards one is likely a git dependency, if your downstream users have read access to your library's source repo. Cargo will handle cloning the repo and checking out the referenced tag or commit for you at build time.

You can also distribute them out of band, and link them as path dependencies. This makes your downstream projects' manifests dependent on the layout of the filesystem, but it's very flexible other than that. A variation on this theme is to include them in the actual source tree of the client modules, as part of a workspace.

If none of these are suitable, you can also run your own registry. This is a fairly involved technical and operational project, not to be done casually, but it does provide some useful capabilities if you need them.

2 Likes

I've never seen them. Since there are so many surely it won't be a problem linking a couple of them?

Indeed. The crate metadata format can change basically every PR we merge. I don't think we have ever had a non-point release which didn't change the format compared to the previous rustc version. As such rustc checks the version string it would emit with rustc -V against the version string embedded in the rlib and refuses to load it in case of a mismatch. Also symbol mangling depends on the rustc version string too, so even at runtime switching out a rust dylib with one compiled by a different rustc version will not work (unless you exclusively use the C abi and #[no_mangle]).

1 Like

then I must have made a mistake, sorry

You don't have to copy over the entire source of your dependency into the consuming code base.

Just point cargo to the directory (or git repo, etc.) where it already is.

Unlike C, Rust has a real, working, and good build system. Don't fight it. Forget invoking rustc. Forget stitching the binary build artefacts together manually.

2 Likes

Those are all alternatives to using rlib files.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.