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

Allow extconf.rb to cancel building the extension #7372

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

casperisfine
Copy link

Ref: https://bugs.ruby-lang.org/issues/20152

There are various gems that ship with a native extension as a way to speedup part of the gem, but also ship with a pure Ruby version of these methods as a fallback. So they only want to compile the extension if the platform supports it, and if not, just fallback Ruby implementation.

Right now users rely on one of two hacks to do this. Either they create an empty Makefile, but then still depend on make being available and it feels very hacky, or they publish platform specific packages without any extension in them.

Examples include bootnsap, erb, hiredis-client, ddtrace, prism.

This changes attempt to make this use case a first class citizen by checking if the extconf.rb did generate a gem.build_skipped file. If it did, make isn't invoked at all.

Ref: https://bugs.ruby-lang.org/issues/20152

There are various gems that ship with a native extension as a way to
speedup part of the gem, but also ship with a pure Ruby version of
these methods as a fallback. So they only want to compile the extension
if the platform supports it, and if not, just fallback Ruby implementation.

Right now users rely on one of two hacks to do this. Either they create
an empty Makefile, but then still depend on make being available and it
feels very hacky, or they publish platform specific packages without any
extension in them.

Examples include `bootnsap`, `erb`, `hiredis-client`, `ddtrace`, `prism`.

This changes attempt to make this use case a first class citizen by
checking if the `extconf.rb` did generate a `gem.build_skipped` file.
If it did, `make` isn't invoked at all.
@segiddins
Copy link
Member

Seems reasonable to me, probably needs to be documented somewhere though 👍🏻

@casperisfine
Copy link
Author

probably needs to be documented somewhere though

Is there an existing documentation for extconf.rb in Rubygems? I can't find it.

Also my plan is to add some skip_compilation method to mkmf on the Ruby side, that would be documented.

@eregon
Copy link
Contributor

eregon commented Jan 15, 2024

One problem with this is the one I explained in https://bugs.ruby-lang.org/issues/20152#note-11:

There could be a skip-make/skip-compilation or so file which does not include RUBY_ENGINE in the filename and is created dynamically by the extconf.rb, but this will take a lot longer to get adopted, as it means each gem skipping compilation would need to use that.
But it is error-prone, because e.g. then if one builds (e.g. rake compile) a gem locally on JRuby and then on CRuby then compilation will be unexpectedly skipped on CRuby, unless the code also takes care of removing that file (I guess mkmf create_makefile could remove it, it seems too annoying if extconf.rb or Rakefile needs to remove it manually).

i.e. specifically it is very error-prone to use this feature until the oldest Ruby a gem supports would have this skip_compilation in mkmf, which will be in a while.
In the meantime, doing things like File.write("gem.build_skipped", "") would cause this problem.

@deivid-rodriguez
Copy link
Member

In principle the idea of not trying to make if there's nothing to make sounds more appealing to me? Is there any downside to that? Could it potentially hinder bugs in extconf.rb files?

@casperisfine
Copy link
Author

Could it potentially hinder bugs in extconf.rb files?

Not that I can think of. I mean if you generate an empty make file by accident today, running a noop make or not running anything shouldn't make a difference.

I went with a different file because it seemed more deliberate, but I'm fine with trying to detect empty Makefile too.

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.

None yet

5 participants