C interface in Rust crate: bloat in staticlib object

⚓ Rust    📅 2026-03-08    👤 surdeus    👁️ 2      

surdeus

I have a Rust crate and I want to expose a C interface for calling into it. For simplicity let's say I have a Rust API with a generic type with some associated functions:

struct Foo<T> (T);

impl<T: Copy> Foo<T> {
  fn get(&self) -> T { self.0 }
  // ...
}

and I want to expose a C API and an object file sort of like

typedef struct (int16_t x) foo16_t;
typedef struct (int32_t x) foo32_t;
typedef struct (int64_t x) foo64_t;

int16_t foo16_get(const foo16_t* foo);
int32_t foo32_get(const foo32_t* foo);
int64_t foo64_get(const foo64_t* foo);

and so on.


I'm unsure about the best practices to produce both a rust .rlib and an object file .a from the same crate. This is what I tried:

I wrote a mod c_api where I have

type foo16_t = Foo<i16>;
type foo32_t = Foo<i32>;
type foo64_t = Foo<i64>;

#[unsafe(no_mangle)]
pub extern "C" fn foo16_get(foo: &foo16_t) { foo.get() }

#[unsafe(no_mangle)]
pub extern "C" fn foo32_get(foo: &foo32_t) { foo.get() }

#[unsafe(no_mangle)]
pub extern "C" fn foo64_get(foo: &foo64_t) { foo.get() }

(The code duplication to instantiate everything twice is not good, but I guess I can fix it with macros and concat_ident). I passed cbindgen over this module to produce the .h header. I made the crate-type = ["lib", "staticlib"]. The problem is: this produces a static lib that's 7MB in size!

Looking with objdump, I see tons of functions that really shouldn't be there: stuff with vec, panic handlers for int overflow, etc. I should emphasize: I built with --release and the crate is no_std. I don't expect panic-on-overflow neither do I expect functions related to Vec.

Like I said, I don't know really know what are the best practices regarding organisation of code in a crate that produces both a Rust and a C interface. How can I ensure the staticlib object only contains a subset of functions, in my case those described in mod c_api and its callees? Split in two crates (the Rust crate with type lib and another crate-c-api with type staticlib that depends on the former)? I tried that and it still builds the same 7MB libcrate.a...

Thanks for any help! It's my first time interfacing with C.

1 post - 1 participant

Read full topic

🏷️ Rust_feed