-
Notifications
You must be signed in to change notification settings - Fork 36
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
Documentation question regarding native extensions #78
Comments
This is a very good question that requires going deep into Bazel to fully answer. Native Extensions are Supported in gem dependencies expressed via Gemfile and AAFAIK We don't currently support building native extensions cross platform. So you could say that the current support within As far as using it with Ruby library and binary, if you can put together a proper example, it would be great to add something under the |
I got this to work here: It's pretty much the same as the linked test file, though. Happy to make an example if you want. |
Yes please put together an example with a decent README. I'm not entirely clear what your build file generates. I think the comment about not fully supporting native extension refers to not having any explicit way to build gems with native extensions across multiple platforms. |
My build generates a shared library (.bundle on macOS, .so elsewhere) native Ruby extension and then makes it a |
Wow, this is a very good example! You probably know more about Bazel than I do 😀 Would love to have a small example like that with a genrule and a c++ library. We could also just reference your BUILD file from our README as an example? |
@sayrer I could really use your help. Can you explain this a bit further to someone who's new to Bazel? I'm also less familiar with platform architectures in relation to the set of problems bazel is trying to solve; it's my understanding that bazel is intended to make the artifact creation process (read: whether that's a compiled binary or whatever) idempotent. I do understand that native extensions pose a challenge to bazel because compilation of ruby gems that reference native extensions implement the dynamically linked shared object libraries that have been compiled for that specific architecure. But what I'm lost on is how bazel necessitates that these native extensions are available for the toolchain to compile ruby idempotently in isolation, irrespective of the host architecture. Just to make any misconceptions I might have more obvious, I'll ask questions more formally:
but if the artifact compiled by bazel makes references to a compiled library on the host system, the "sandbox" is leaking to host-compiled dependencies. My understanding is that a host that has compiled a native extension may have other dependencies that bazel is not aware of, thus breaking the idempotency of the overall build.
Any help you can provide would be appreciated. Really, even if it's a one-sentence response, it'll help me dig. |
If you mean this line: then it's possible to make this pretty tight. That is an .so file built by Bazel. So if I change the Rust/C++ that make up that library from another directory, the Ruby binary will require a rebuild (probably just a file copy here). I don't think this project bothers to make the C/C++ toolchain really hermetic, but it certainly could. See for example: https://github.com/buildbuddy-io/buildbuddy-toolchain In general, practicing these concepts on a free BuildBuddy account is a good way to go. They provide a lot of dashboards and things so you can see how things are working. I think this project has a few references to host binaries because I was hitting bugs with the sandbox, but I think they'll probably be fixed now.
Yeah, it's covered here: You can build for Linux-ARM64 on Linux-x64, for example. But you can't build every platform from every platform (e.g. macOS, iOS, require an Apple host).
Ah, so when you initialize the Workspace, it will compile a copy of Ruby (or it can use the host) [edit: it looks these rules always depend on a host version, but I bet you could make it work via rules_nix as used in this project for SWIG]. So, there will be a copy of Ruby in your bindir that depends only on what's in your workspace, and a copy of those headers. These directories are available for each platform in debug and release mode. See here:
See how it refers to Bazel's copy of the Ruby headers in Then, we decide how to build the shared library based on the target architecture.
So, here decides which architecture to build for, and that will require C++/Rust builds for the target architecture. Basically, it works backward from the target binary's requirements. You'd get the default condition there for all Linux architectures, but it would build it for both x64 and ARM if you were trying to do both. |
I was initially mislead by README content that says: "Building native extensions in gems with Bazel" is not yet supported.
Is non-gem support for native extensions documented somewhere? I eventually found
https://github.com/bazelruby/rules_ruby/blob/master/ruby/tests/BUILD.bazel#L186
so it seems like it is possible to use native extensions in
ruby_binary
andruby_library
, but I only figured this out because the@org_ruby_lang_ruby_toolchain//:headers
rule seems designed to support this use case.The text was updated successfully, but these errors were encountered: