Skip to content

Conversation

@jonbarlo
Copy link
Contributor

What was the end-user or developer problem that led to this PR?

Closes

It was premature to deprecate Gem.install_extension_in_lib == true when we have not even yet changed libraries that could break when the path changes to ext/

@deivid-rodriguez suggestion was
"While I think explicit deprecation of Gem.install_extension_in_lib == true is great, I believe the issue is more that some gems actually rely on the compiled extension being placed in the lib folder to work, so once we toggle the default, they will break. If I recall correctly, the problem was gems using ffi-compiler.

So my idea was to:

Figure out what ffi-compiler should be doing instead to play nice with RubyGems.
Propose that change to ffi-compiler.
Figure out how to warn other cases we may be missing, and cases where an old version of ffi-compiler not including our fix is used.
One potential idea I just had is to temporarily keep installing a wrapper file into lib that warns and then loads the extension from the proper location."

This PR includes the work related to this part in specific.
"One potential idea I just had is to temporarily keep installing a wrapper file into lib that warns and then loads the extension from the proper location."

What is your fix for the problem, implemented in this PR?

install with extension_in_lib option will add ruby wrapper file including ext/ folder path

Make sure the following tasks are checked

@deivid-rodriguez
Copy link
Contributor

My understading is that this PR is create a .rb wrapper to load the extension from ext/ folder in the installed gem rather than from lib/. This is not going to work because I don't think there's a compiled extension at all in ext/, just the sources.

We'd need to load the file from rubygems arch specific extension directory for the gem.

Se for example the copies installed for json:

$ tree /Users/deivid/.local/share/mise/installs/ruby/3.4.5/lib/ruby/gems/3.4.0/gems/json-2.13.2/lib/json/ext 
/Users/deivid/.local/share/mise/installs/ruby/3.4.5/lib/ruby/gems/3.4.0/gems/json-2.13.2/lib/json/ext
├── generator
│   └── state.rb
├── generator.bundle
└── parser.bundle

2 directories, 3 files

$ tree /Users/deivid/.local/share/mise/installs/ruby/3.4.5/lib/ruby/gems/3.4.0/extensions/arm64-darwin-24/3.4.0/json-2.13.2/json/ext 
/Users/deivid/.local/share/mise/installs/ruby/3.4.5/lib/ruby/gems/3.4.0/extensions/arm64-darwin-24/3.4.0/json-2.13.2/json/ext
├── generator.bundle
└── parser.bundle

1 directory, 2 files

We'd want to install the wrapper file in the first location, and load the compiled file in the second location from it.

However, using a .rb wrapper has at least two problems:

  • It doesn't work if there's already a .rb file with the same name (it would overwrite the actual gem sources).
  • It doesn't work if the extension is required explicitly through things like require_relative "library/library.so" or require_relative "library.so".

So the only solution would be that the wrapper library has the same extension as the compiled extension it's replacing, in the case, .bundle.

@deivid-rodriguez
Copy link
Contributor

Also, note that this change is unrelated to ffi-compiler by the way. There are both gems based on ffi-compiler and not based on ffi-compiler affected by this.

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