-
Notifications
You must be signed in to change notification settings - Fork 240
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
[Discuss] Could bindings generators live in separate crates? #299
Comments
I agree with all of your above; especially around Gecko, and backends from contributors. It might be worth writing down the necessary pre-conditions before we'd consider doing this:
FWIW: I think as we get closer to maturity for the shape of how backends should be written, the python binding will be easier to review, test and keep up. I'm optimistic now |
I've been thinking a bit more about this in the context of #435 and the resulting Ruby backend. I think I was actually over-complicating it in my head a bit, and we more-or-less have all the pieces that we'd need to start restructuring things in this way. Currently the
We can leave the first of those jobs intact in the main The Consumer ViewFor running on the command-line, users would need to install both the When invoking
Would in turn shell out to the kotlin-specific backend like:
A similar setup could work for test scripts, although we'd have to think a bit about the command-line API surface for that one. When it sees the The user doesn't have to know about any of that, however - they just have to know to install the backends they want. For users who want to integrate into a broader build system rather than installing the tools at the system-level, we could support an extension of the pattern used in application-services. The consumer would need to make a wrapper crate that depends on all three of
And then executing that via This could actually be a small concrete win for the application-services build setup, because we wouldn't need to compile the Python or Ruby or other backends as part of the application-services build. Notably absent here is the need for any sort of serialized internal representation to be passed between the executables - everything they need to know is already in the The Developer ViewTo make writing language backends as simple as possible, we would try to keep as much infrastructure as possible in the
Perhaps we could also publish some of our testing crates in a way that the individual language backends could import and use them, spreading out e.g. One risk here is that we amplify the cost of breaking changes, and particularly of breaking changes in the "ABI" of how data gets lifted and lowered. My personal sense is that it will be worth the reduction in overall system complexity that we get from splitting things into more separable components. |
How would that plan fit with #416? |
I think it would be OK, because the code for each backend doesn't need to actually parse the |
Thinking of taking a shot at this for the hack week! I Will drop updates here and in a possible draft PR / other repo for demo purposes... |
@rfk @tarikeshaq I'm interested in the work around moving language binding generators into their own crates/repos. Is this something an external contributor (not from mozilla or uniffi-rs team) can pick up? Do we have to continue from #997 or can we start fresh? I'm super excited about uniffi-rs and the general idea of rust being a kind of a universal language and I have ideas for different flavors of languages etc (for example a functional bindings generator for kotlin which doesn't throw but returns Result<T, E>) and different languages. In the near term, I'll be needing a TypeScript bindings generator as well and for the pace of development, I'd like to ensure this work is completed first. If this is something you're open to, I'm willing to put in the time and energy towards this effort as this is super important to me. Please let me know how I can contribute. Regarding testing, I think the different binding generators can have their own test suites and the community can decide whether a binding generator is well tested or not before they use them, and the current generators can also be moved out safely into repos owned by the same team but links to these repos/crates can be presented in the README as reference, or can be included as default if that is super important (to guarantee test coverage etc). Apologies if I'm talking too much, I'm just super excited about this. |
I have a question - why do we call it 'backend'? |
Hi @artfuldev, thanks for reaching out!
I should start out by saying, I'm not longer with Mozilla and am contributing much less to uniffi-rs these days, but I'm still pretty excited by the idea of allowing generators to live in separate crates and would be happy to help review things if you want to try implementing it. I expect there's still quite a bit of interest in this from the Mozilla folks.
I don't think it's necessary to start from #997 (especially as it seems a bit stale with merge conflicts) but it's probably worth taking at look at for some inspiration at least. A lot of #997 is about moving the existing Kotlin code-generator around, but if you ignore the Kotlin-specific parts, does what that PR is trying to do make sense (perhaps in conjunction with my comment above?
A different way to get started here may actually be to implement one of these backends directly in your own fork of UniFFI alongside its existing backends, as a way to just get more familiar with the codebase and what exactly is entailed in implementing a backend. Once you've got it working inline in the crate there, you'll probably have a good mental model of what would be required to pull the backends out into a separate crate. |
I second what @rfk said: Mozilla folks are definitely interested in this and I think that plan to get started makes a lot of sense. If you're on element, feel free to reach out on the uniffi channel (I think it's #uniffi:mozilla.org). "Backend" means either the bindings or scaffolding. I think it comes from a compiler metaphor: UniFFI is compiling the UDL code and the target output is the Rust/Kotlin/Python/... code. |
Just want to update here that the additional language bindings have fallen a little lower on the priority list for us. Right now we want to get the most out of the swift and kotlin bindings that already work so well (thanks for the amazing work on those). I will get back to this when the additional language support becomes a high priority item for us again - which can be in a few weeks. |
I'll be re-picking this up, we have upcoming work that can benefit from the separation of the binding generators |
Yes, I think something like that would be good, although I think we should start fresh rather than trying to resurrect 1205. I was just talking to @mhammond about this yesterday, we hope to do it at some point, but nothing is scheduled. Is there a particular use case that splitting up the crates would accomplish? |
I think separating out the the language bindings generators would really help with 3rd party language support by making the official examples look more like 3rd party language crates. It'd also help make sure there aren't breaking-API changes. I'm trying to bring the Kotlin Multiplatform (https://gitlab.com/trixnity/uniffi-kotlin-multiplatform-bindings) UniFFI bindings up-to-date with the latest version. I'm still getting up-to-speed, so maybe I just don't understand everything fully yet. |
Thanks - that's exactly the context in which Ben and I were discussing it. So while we support this, as Ben said, it's not something we have on our short-term plate so would welcome contributions here! |
We'd also welcome other changes which make life easier for 3rd party bindings - eg, |
I had another look at #1205, and I'm not quite sure I like that each binding is split into its own crate - I think I'd personally mildly prefer a single "uniffi_bindings" crate which held all the builtin languages. I think this would still offer most of the advantages mentioned above (ie, just not being in @bendk WDYT? |
For our current stage of development, I like the way that we currently bundle the bindings generators for all languages as part of the main
uniffi_bindgen
crate. It simplifies testing and it (mostly) ensures that we don't leave any languages behind. But I wonder if it's the right thing long term:Other projects in the Rust ecosystem appear to have had some success in externalizing specific backends into separate crates, e.g. serde. What would it look like for us to take a similar approach, and when (if ever) would it be worth the costs of doing so?
┆Issue is synchronized with this Jira Task
┆Issue Number: UNIFFI-26
The text was updated successfully, but these errors were encountered: