Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add a static library crate with a C FFI #21

Merged
merged 20 commits into from
May 16, 2024
Merged

Conversation

hulthe
Copy link
Contributor

@hulthe hulthe commented May 13, 2024

This let's us compile maybenot to a static library and use it in non-rust programs with support for C FFIs

@hulthe hulthe force-pushed the ffi branch 2 times, most recently from fa7ab5e to 2923671 Compare May 14, 2024 07:52
@hulthe hulthe changed the title [WIP] Add a static library crate with a C FFI Add a static library crate with a C FFI May 14, 2024
@hulthe hulthe marked this pull request as ready for review May 14, 2024 08:25
@hulthe
Copy link
Contributor Author

hulthe commented May 14, 2024

@pylls hey, we talked about upstreaming our ffi wrapper. Here it is :)

crates/maybenot-ffi/Makefile Outdated Show resolved Hide resolved
crates/maybenot-ffi/Makefile Outdated Show resolved Hide resolved
@pylls
Copy link
Contributor

pylls commented May 14, 2024

Many thanks @hulthe and @faern!

FFI wrapping and the specific needs here are not something I'm familiar with. Happy to see that it's cleanly separated from the other crates.

Once the requested change is made and you're both happy, please merge this @faern .

crates/maybenot-ffi/maybenot.h Show resolved Hide resolved
crates/maybenot-ffi/Makefile Outdated Show resolved Hide resolved
crates/maybenot-ffi/src/error.rs Outdated Show resolved Hide resolved
Copy link
Collaborator

@faern faern left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some smaller notes, but they are not critical items, would potentially just be nice to have.

Also going to write here what I said in the office: Personally I prefer that we ditch cbindgen as a build time dependency. It pulls in 20+ dependencies in our dependency chain. Both a supply chain risk and maintenance burden as well as a compile time time cost. I'm positive towards automatically generated bindings if the source changes frequently, so manually doing it is a burden. But for this API it will likely change extremely seldom, so manually updating the header when needed has very little downsides.

/// `actions_out` must have capacity for [maybenot_num_machines] items of size
/// `sizeof(MaybenotAction)` bytes.
///
/// The number of actions will be written to `num_actions_out`.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More items for the safety docs, if they should be complete:

  • num_actions_out must also be a valid pointer where a 64 bit int can be written
  • "this must be a valid pointer to a [MaybenotFramework] instance"

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

) -> usize {
let num_actions = self
.framework
.trigger_events(&[convert_event(event)], Instant::now())
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Here the API is changed from "list of events" (Rust) to "single event" (C). We can leave it like this for now. But I suspect we might revisit this in the future to make the API as similar to Rust as possible, and also we might hit performance bottlenecks making us want to batch event processing (like the Rust code allows)

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good points. I've recently become aware that certain languages (cough Go cough) make FFI calls significantly more expensive, which means we might as well consider doing it now. I can have a look and see if it would be an annoying change to make for our existing project that depends on this crate.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately there's now a bit more code to review... 😔

Copy link
Collaborator

@faern faern left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice!

@faern faern merged commit e911b6b into maybenot-io:main May 16, 2024
1 check passed
faern pushed a commit that referenced this pull request May 16, 2024
* Add maybenot-ffi

* Add makefile and readme

* Run cbindgen in build script

* Embed crate version in static library

* Correctly expose crate version using a function

instead of a static &CStr, which is not FFI safe

* Move mod statements below use

* Make public Rust API be same as public FFI API

* Pin cbindgen to avoid any format change surprises

* Remove obsolete error type

* Remove thiserror

* Remove default cbindgen.toml options

* Remove --locked

* Respect CARGO_TARGET_DIR in makefile

* Commit Cargo.lock

Also remove cbindgen version pin, since version pinning in
Cargo.toml has problems when dealing with multiple versions of the
some package in the dependency tree.

* Set ffi lib version to 1.0.0

* Add maybenot-ffi to /README.md

* Tighten restriction on null bytes in version str

* Remove machine string filtering & trimming in ffi

* More safety docs

* Change on_event ffi func to accept multiple events
@faern
Copy link
Collaborator

faern commented May 16, 2024

@hulthe Great work, let's use this! 💪

@pylls I was happy with the FFI bindings so I merged them. This also means we merge the Cargo.lock for the entire workspace. This should not make a huge difference in any way. It mostly makes debugging issues related to dependency upgrades and downgrades easier.

We will work on migrating this to v2 a bit later once v2 is stabilized and we start migrating to it.

@pylls
Copy link
Contributor

pylls commented May 16, 2024

Many thanks @hulthe and @faern ! :)

@hulthe hulthe deleted the ffi branch August 6, 2024 10:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants