oxidize-rb / rb-sys

Easily build Ruby native extensions in Rust
https://oxidize-rb.github.io/rb-sys/
Apache License 2.0
221 stars 34 forks source link

Binaries installed into subdirectories based on Ruby version - incompatible with how bundler's Rust extension template works #312

Open taylorthurlow opened 7 months ago

taylorthurlow commented 7 months ago

I had no issues getting my Rust extension working locally, but one of the issues I ran into was using the cross-compile action. Once I got the build working, the resulting gem packages were built with the precompiled binary in a path like lib/my_gem/3.0/my_gem.bundle. This is incompatible with the extconf.rb generated by Bundler. The local build generates lib/my_gem/my_gem.bundle.

# lib/my_gem/extconf.rb as generated by Bundler

# frozen_string_literal: true

require_relative "my_gem/version"
require_relative "my_gem/my_gem"

module MyGem
  class Error < StandardError; end
end

I saw that wasmtime seemed to have the same problem, and they fixed it like so:

# lib/my_gem/extconf.rb

# frozen_string_literal: true

require_relative "my_gem/version"

# Tries to require the extension for the given Ruby version first
begin
  RUBY_VERSION =~ /(\d+\.\d+)/
  require "my_gem/#{Regexp.last_match(1)}/my_gem"
rescue LoadError
  require_relative "my_gem/my_gem"
end

module MyGem
  class Error < StandardError; end
end

EDIT: Looks like specifying a single Ruby version target gets you the standard my_gem/my_gem.bundle, multiple gets you the subdirectories. Understandable, but worth mentioning.

ianks commented 4 months ago

Yeah, it's a bit of a hack but that's the recommended rake-compiler pattern so I went with it... Would def accept a patch to document this better.