Can rust directly depend on xxx.so or xxx.a compiled by other rust crates?

I have a crate named crate2, which depends on crate1, but there is no source code for crate1, only the libcrate1.a or libcrate1.so it generates. How do I build crate2 so that it generates rlib?

crate2:

use crate1::sjh_add;

pub fn add(left: usize, right: usize) -> usize {
    sjh_add(left, right)
}

Usually, I need to specify the source code path of crate1 in the Cargo.toml file.

[package]
name = "crate2"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
crate1 = {path="../crate1"}

Is there a way to directly specify the libcrate1.so or libcrate1.a when compiling crate2?
The function in crate2 is not #[no_mangle].

If you don't have the source code of crate1, crate1 will have to export a C interface which you then need to bind against in crate2 like any other C library. Rust doesn't have a stable ABI, so unless crate1 is compiled with the exact same rustc version, there is no way to handle it like a rust crate.

1 Like

Here is great (and instructive) example:

pub enum Foo {
    A = 2,
    B = 3,
}

pub fn foo() -> Option<Foo> {
    None
}

pub fn bar(x: Option<Foo>) -> bool {
    x.is_none()
}

rustc 1.56.0 uses 4 for Option<Foo>::None while rustc uses 1 for it.

As you can guess if one crate puts 1 and some other one expects to see 4 there (or the other ways around) then resulting program… may misbehave a bit.

IOW: not only such use is not encouraged, it's actually actively not supported.

There is no stable abi for rust so far, so even the same compiler version may generate different but legal binary forms, so the best solution is to use c abi as the medium of interaction.