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

WIP: Build C bindings dylib for Ruby (also introducing: Ruby bindings) #280

Closed
wants to merge 7 commits into from

Conversation

machty
Copy link

@machty machty commented Nov 29, 2024

Hello! I have what I hope will be considered exciting news:

Ruby Bindings for ZEN Engine

https://github.com/FutureProofRetail/zen-engine-ruby

I had a need for evaluating rules in a Ruby context and noticed that there are no plans to develop or support Ruby bindings. As a result, I started working on my own implementation here: https://github.com/FutureProofRetail/zen-engine-ruby.

The project is still very much in alpha—it's prone to crashing about half the time due to a double-free pointer error that I believe is relatively straightforward to fix; I just need to address something in our use of the Ruby FFI gem. You can view the remaining issues I'm aware of here: https://github.com/FutureProofRetail/zen-engine-ruby.

Is it okay to host this under our repo/org?

I chose to develop the Ruby bindings in a separate repository because:

  • I wasn't sure if the GoRules team would be interested in supporting it, so it seemed inappropriate to include it in the main repository.
  • The Golang bindings have their own repository, which served as a useful reference for us.

That said, while the Golang repository is housed under the gorules GitHub organization, I am open to transferring our work there if there is a strong desire for it. However, if it seems likely that the Ruby bindings will receive limited support from the gorules team, it might be better to continue hosting them in our own organization.

Implementation Approach for Ruby Bindings (help needed)

Ruby is an interpreted language, and the easiest way to implement FFI with languages like Rust is by using the FFI Ruby gem. This gem allows you to define an interface to shared libraries (.so, .dylib) through a Ruby interface without requiring users to compile native extensions when installing your gem.

To proceed, I need a cdylib version of the C bindings within this repository. My familiarity with this area is limited, so when I added cdylib to the crate-type array, I started encountering build errors due to unimplemented Go functions. After adding a few feature flags, I was able to compile things on my Mac, which allowed me to move forward with getting the Ruby bindings to pass tests.

We definitely need to clean this up, but I could use some guidance:

  1. Is it correct to change crate-type to crate-type = ["cdylib", "staticlib"]?
  2. Do you have any suggestions for resolving the Go errors?
  3. I see a few features are included, such as "bincode." Should those be enabled during compilation? Are there other important features to consider?
  4. Moving forward, what is the best way to periodically build the cdylibs for the Ruby bindings? I'm not sure how the Golang repository does it; do they update the dylibs based on a CI build or run a local Docker script?

I appreciate any help you can provide. I submitted this as a PR to include my attempts to build the cdylibs instead of opening an issue. If I can reach an agreement with the gorules team on how to proceed, I’m happy to make the necessary changes here.

@stefan-gorules
Copy link
Contributor

Hi, thanks for the contribution @machty.

The code looks good and happy to merge this once it's ready. For Ruby, I would most likely opt for approach with: https://github.com/matsadler/magnus instead of the one you've taken. Our preferences is to use a tool where applicable (if it exists) to manage the language binding. For Go, no such thing exists yet, hence the seperate repository (also Go doesn't have package management, and relies on git, so we needed it anyway).

Regarding your questions:

  1. Is it correct to change crate-type to crate-type = ["cdylib", "staticlib"]?
    • This depends on how Ruby operates under the hood. As it likely requires cdylib, we would need 2 different configurations, one for Golang, one for Ruby.
  2. Do you have any suggestions for resolving the Go errors?
    • Could you explain what you mean by Go errors? I assume you mean compilation errors, which would be resolved by utilising 2 separate configs, or opting to use magnus instead.
  3. I see a few features are included, such as "bincode." Should those be enabled during compilation? Are there other important features to consider?
    • No features are needed, even bincode might be removed in future as we don't have a practical use case for it yet.
  4. Moving forward, what is the best way to periodically build the cdylibs for the Ruby bindings? I'm not sure how the Golang repository does it; do they update the dylibs based on a CI build or run a local Docker script?
    • We'll look into unifying release process at some point. For golang, we release it via GitHub pipelines.

@machty
Copy link
Author

machty commented Dec 4, 2024

Ah, I searched but I failed to find something like magnus.

I am happy to rework things to use magnus if it is not an incredible effort, but for now we are likely to move forward with our now-published gem and see what we're able to build. If everything works out we can take another look at magnus.

Do you have any suggestions for resolving the Go errors?

I meant the linker errors I was getting due to unimplemented Go-centric functions (zen_engine_go_loader_callback and zen_engine_go_custom_node_callback).

@stefan-gorules
Copy link
Contributor

Hi @machty, just an update on this side. We'll be adding uniffi through the kind contribution on #298. If you're still interested in Ruby, we can add the support directly through uniffi as it's supported.

Is this something you're still interested in?

@machty
Copy link
Author

machty commented Feb 10, 2025

The project that motivated this work is deferred but when it resumes I will let you know (or take a stab at uniffi integration) myself.

@stefan-gorules
Copy link
Contributor

Sounds good! I'll close this for now.

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.

2 participants