# Embeddig C code into Rust crate

**URL:** <https://internals.rust-lang.org/t/embeddig-c-code-into-rust-crate/4838>\
**Category:** Uncategorized\
**Created:** [February 22, 2017, 10:55pm UTC](https://internals.rust-lang.org/t/embeddig-c-code-into-rust-crate/4838 "2017-02-22T22:55:11Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![anatol](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/anatol/32/746_2.png) [@anatol](https://internals.rust-lang.org/u/anatol)\
**Post date:** [February 22, 2017, 10:55pm UTC](https://internals.rust-lang.org/t/embeddig-c-code-into-rust-crate/4838/1 "2017-02-22T22:55:11Z")

</div>

Hi folks

I have a crate that adds bindings for a large C library. Rust bindings to shared library are easy to use. But there are some issues with current solution:

- Binding assumed to link application to a shared library installed at the target computer’s LD\_PATH. What if target computer does not have shared libraries support (e.g. an embedded device or custom OS).
- Compiled application is not hermetic. i.e. it requires that users installed additional system packages. Every operation system has its own way to install shared libraries and it complicats installation. What if OS does not have a suitable package? What is user does not have “install additional package” permissions?
- It is hard to control for a user what version of system library is installed. What if a user needs libFoo.2.6 when system provides libFoo.1.2 only?
- Keeping code in a shared library prevents to perform Link-Time-Optimization over whole project.

It would be interesting to see a way to embed a C library into Rust crate and share as one hermetic thing without external dependencies. The C code will be part of the Rust crate and distribute as a whole thing. Then cargo/rustc compile both C and rust into bytecode and process it together.

Is there anything like this possible today?

---

<div class="post-metadata">

**Author:** ![mattico](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/mattico/32/3021_2.png) [@mattico](https://internals.rust-lang.org/u/mattico)\
**Post date:** [February 23, 2017, 10:33pm UTC](https://internals.rust-lang.org/t/embeddig-c-code-into-rust-crate/4838/2 "2017-02-23T22:33:20Z")

</div>

I think this question would be better suited to [https://users.rust-lang.org/](https://users.rust-lang.org/), unless you’re interested in compiler changes that would make this use case easier?

It sounds like what you want are static libraries/static linkage. On linux musl can be used to create a completely static binary, as described in [the [old] book](https://doc.rust-lang.org/beta/book/advanced-linking.html). On other platforms you still need to dynamically link to system libraries, but you can still statically link libraries as described in the [ffi section of the book](https://doc.rust-lang.org/book/ffi.html#linking). I believe that LTO works when linking Rust and C code, although you have to build the C code with Clang because the LTO object files are really just LLVM bitcode.

---

<div class="post-metadata">

**Author:** ![kornel](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kornel/32/2711_2.png) [@kornel](https://internals.rust-lang.org/u/kornel)\
**Post date:** [February 23, 2017, 10:44pm UTC](https://internals.rust-lang.org/t/embeddig-c-code-into-rust-crate/4838/3 "2017-02-23T22:44:25Z")

</div>

It is possible. You can build the C library as static `libfoo.a` and link it with Rust.

You could include the C library in your crate and build it yourself (or with the [`cc`](https://crates.rs/crates/cc) crate), you could try to find suitable one on the system with [`pkg-config`](https://crates.io/crates/pkg-config) (you can ask it for static linking). If the versions are very different, but you still want to support all of them, you can run `bindgen` in your `build.rs`.

---

<div class="post-metadata">

**Author:** ![retep998](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/retep998/32/729_2.png) [@retep998](https://internals.rust-lang.org/u/retep998)\
**Post date:** [February 24, 2017, 1:54am UTC](https://internals.rust-lang.org/t/embeddig-c-code-into-rust-crate/4838/4 "2017-02-24T01:54:12Z")

</div>

> [@mattico](#):
>
> I believe that LTO works when linking Rust and C code

At the moment Rust emits fully compiled object files and libraries for the linker to link. External libraries are simply passed to the linker (or bundled into an rlib and passed that way) but never does Rust do LTO with external libraries. There is no LTO between Rust and C at the moment, but maybe in the future there could be.

---

<div class="post-metadata">

**Author:** ![anatol](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/anatol/32/746_2.png) [@anatol](https://internals.rust-lang.org/u/anatol)\
**Post date:** [February 24, 2017, 4:09am UTC](https://internals.rust-lang.org/t/embeddig-c-code-into-rust-crate/4838/5 "2017-02-24T04:09:31Z")

</div>

Thank you for your answers folks.

> [@kornel](#):
>
> You could include the C library in your crate and build it yourself (or with the gcc crate), you could try to find suitable one on the system with pkg-config (you can ask it for static linking). If the versions are very different, but you still want to support all of them, you can run bindgen in your build.rs.

I wonder if cargo/Rust can do something better here. It would be nice to see a simpler integration, for example Cargo.toml specifies embedded C files and compile flags and Cargo takes care of compilation under the hood. It will probably need external `clang` that produces LLVM IR consumed by Rust.

---

<div class="post-metadata">

**Author:** ![kornel](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kornel/32/2711_2.png) [@kornel](https://internals.rust-lang.org/u/kornel)\
**Post date:** [February 24, 2017, 1:31pm UTC](https://internals.rust-lang.org/t/embeddig-c-code-into-rust-crate/4838/6 "2017-02-24T13:31:06Z")

</div>

I don’t think so. Cargo used to support simpler integration (you could launch `make` from Cargo.toml) and that has been removed.

Just adding C files doesn’t help you use them from Rust. You need to convert the header files, and even then you end up with a bunch of `unsafe` functions that aren’t as convenient as native Rust ones.

So the current approach is to make bindings as a \*-sys crate that enables easy linking with the C library, and then create a higher-level safe Rust wrapper for it.

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [March 25, 2019, 8:28am UTC](https://internals.rust-lang.org/t/embeddig-c-code-into-rust-crate/4838/7 "2019-03-25T08:28:01Z")

</div>

Closed on March 25, 2019, 8:28am UTC

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.
