Replies: 3 comments 1 reply
-
I think option 3 is indeed the way to go, and would nicely solve this and related issues. The mapping from existing Gem platforms would be (IIUC):
For FFI gems or also sorbet-runtime, where the precompiled binaries depend on the native platform but does not use an extension API, they would opt-in to
How do we fit Related: #2945 |
Beta Was this translation helpful? Give feedback.
-
If we want to be lazy, then yes, though if we wanted to be clever we could scan the binaries for references to the CRuby Extension API and if missing, then mark them as FFI
Yes, though I just realized that for consistency, unless they are shipping java sources to be compiled, it should probably be "jruby-bin". Unsure if that's a useful distinction for JRuby. In contrast, for CRuby (cruby, cruby-bin) vs TruffleRuby (only cruby) it does make sense, though.
Well, I proposed
If you are talking about source C extensions, then no, that would be
That's a good point, I conceptually think of it as part of the ABI, At the very least, GCC tacks it on like the ABI: Another key thing I didn't mention about option 3 is that we would need to really focus on updating docs and learning/getting started material as it would change the way gem developers need to think about the platform. |
Beta Was this translation helpful? Give feedback.
-
I also like proposal 3, if we can make it happen. This question has been lingering for a decade at least with little progress. The main problem that has always blocked us from improving the platform system is the encoding of platform in the gem name. The platforms are selected by looking at the gem filename, to avoid opening each file and looking for platform metadata... so gems prebuilt for Windows are blah-gem-0.1-mswin32.gem and gems for JRuby are blah-gem-0.1-java.gem. In order to have more dimensions to the platform, we may have to abandon having all platform information encoded in the filename.
We have never supported this and I consider it pretty unnecessary, but it raises the question of JRuby gems that depend on a specific level of JDK... should the platform include a version number? Obviously this quickly becomes unworkable. Our recommendation in general is that your precompiled JRuby extension should support all Java versions that the target JRuby supports. For 9.3 and 9.4, this is Java 8, 11, and 17. For JRuby.next, we may jump to 17 only. I will also point out there are parallel discussions about adding metadata to gems to define system-level dependencies (C libraries, OS packages, etc). |
Beta Was this translation helpful? Give feedback.
-
Currently, the major Ruby implementations all support FFI, but there isn't a convenient way to distribute pre-built binaries via rubygems in an engine-agnostic way. CRuby and TruffleRuby can download the correct pre-built binary gems (like
ffi-libarchive-binary
) for their host platform (ie.x86-linux
, etc), while JRuby, has the platform ofjava
being undifferentiated by the underlying platform. As such, to package pre-built binaries for all of the 3 major Ruby implementations, one must make separate loading logic and archives for native platforms (just the correct binary), and the java platform (all binaries of all underlying platforms must be included)I would like to propose a new feature to differentiate pre-built or underlying platforms from the current system of differentiating post-install built platforms. I see a few ways this can be done:
ffi-
for gems that don't build or differentiate based on the Ruby platform, typically as they use FFI to access any included artifacts. Thus CRuby would try, for examplex86-linux
andffi-x86-linux
, while JRuby would tryjava
andffi-x86-linux
. Post-install gems can use this too if they want to only install on some platform, regardless of being JRuby or not. This is the simplest to do today.engine_invariance
or such that has the same affect as option 1api
property that is separate from the platform, and change howplatform
works. This involves a large migration, but I think is the most sane when taking a big picture approach. Native extension gems that use CRuby's C API would thus move to, for example,{api: "cruby", platform: "x86-linux"}
, native extension gems that use JRuby's API would be{api: "java", platform: "x86-linux"}
, and FFI gems would be something like{api: "ruby", platform: "x86-linux"}
(unsure if"ruby"
ornil
or something else is better here). This would also work towards solving this issue, as prebuilt CRuby extensions could beapi: "cruby-bin"
which TruffleRuby could reject while allowingapi: "cruby"
in source form. Note that this IS NOT a proposal to encode the engine, but the extension API's that are required of the engine, hence why MRI and TruffleRuby both would support downloading similar gems. Install-time building of FFI binaries, like whatsassc
does, would be something like{api: "ruby", platform: nil }
I think option 3 is the most cogent and logically defensible for the long term, but it involves breaking a lot of compatibility and assumptions in gems along the way. Thoughts on these or any other options?
cc @headius @eregon @hsbt
Beta Was this translation helpful? Give feedback.
All reactions