jruby / docker-jruby

MIT License
18 stars 27 forks source link

Include GNU make in docker images to avoid issues while installing native gems #81

Closed ivoanjo closed 1 year ago

ivoanjo commented 2 years ago

Hello there! As always, thanks for JRuby and for having nice docker images that can be used easily :)

I work at @Datadog on the ddtrace gem. We support JRuby in most functionality provided by the gem, but we have an optional native extension that is MRI/CRuby-specific.

The way we make the extension "optional" is by having an extconf.rb that generates an effectively-empty Makefile. (Reference: https://github.com/DataDog/dd-trace-rb/blob/master/ext/ddtrace_profiling_native_extension/extconf.rb#L35).

I've seen this approach being used by other gems as well. mkmf actually includes a dummy_makefile method, and a few other gems use it:

Unfortunately, this approach breaks if GNU make is not installed because Rubygems will still try to call "make" and blow up since it's not available, even though the Makefile was an empty one just to make Rubygems happy.

TL;DR: Would it be reasonable to include make by default in the docker images so that rubygems doesn't break when installing these no-op extensions?

For context, this is what get with the current docker images:

For ddtrace:

root@docker-desktop:/# gem install ddtrace
Fetching ddtrace-1.5.0.gem
Fetching libddwaf-1.3.0.2.0.gem
Fetching libdatadog-0.7.0.1.1.gem
Fetching debase-ruby_core_source-0.10.17.gem
Successfully installed libddwaf-1.3.0.2.0
Successfully installed libdatadog-0.7.0.1.1
Successfully installed debase-ruby_core_source-0.10.17
Building native extensions. This could take a while...
ERROR:  Error installing ddtrace:
    ERROR: Failed to build gem native extension.

    current directory: /usr/local/bundle/gems/ddtrace-1.5.0/ext/ddtrace_profiling_native_extension
/opt/jruby/bin/jruby -I /opt/jruby/lib/ruby/stdlib -r ./siteconf20221004-195-10or6zf.rb extconf.rb

+------------------------------------------------------------------------------+
| Could not compile the Datadog Continuous Profiler because                    |
| JRuby is not supported by the Datadog Continuous Profiler.                   |
|                                                                              |
| The Datadog Continuous Profiler will not be available,                       |
| but all other ddtrace features will work fine!                               |
|                                                                              |
| Get in touch with us if you're interested in profiling your app!             |
+------------------------------------------------------------------------------+

current directory: /usr/local/bundle/gems/ddtrace-1.5.0/ext/ddtrace_profiling_native_extension
make DESTDIR\= clean
sh: 1: exec: make: not found

current directory: /usr/local/bundle/gems/ddtrace-1.5.0/ext/ddtrace_profiling_native_extension
make DESTDIR\=
sh: 1: exec: make: not found

make failed, exit code 127

Gem files will remain installed in /usr/local/bundle/gems/ddtrace-1.5.0 for inspection.
Results logged to /usr/local/bundle/extensions/universal-java-17/2.6.0/ddtrace-1.5.0/gem_make.out

For bootsnap:

root@docker-desktop:/# gem install bootsnap
Fetching msgpack-1.6.0-java.gem
Fetching bootsnap-1.13.0.gem
Successfully installed msgpack-1.6.0-java
Building native extensions. This could take a while...
ERROR:  Error installing bootsnap:
    ERROR: Failed to build gem native extension.

    current directory: /usr/local/bundle/gems/bootsnap-1.13.0/ext/bootsnap
/opt/jruby/bin/jruby -I /opt/jruby/lib/ruby/stdlib -r ./siteconf20221004-94-1cfgani.rb extconf.rb

current directory: /usr/local/bundle/gems/bootsnap-1.13.0/ext/bootsnap
make DESTDIR\= clean
sh: 1: exec: make: not found

current directory: /usr/local/bundle/gems/bootsnap-1.13.0/ext/bootsnap
make DESTDIR\=
sh: 1: exec: make: not found

make failed, exit code 127

Gem files will remain installed in /usr/local/bundle/gems/bootsnap-1.13.0 for inspection.
Results logged to /usr/local/bundle/extensions/universal-java-17/2.6.0/bootsnap-1.13.0/gem_make.out
headius commented 2 years ago

It would be logical to include appropriate tools to build e.g. libsass. Is make enough? I would assume we'd also need gcc and autotools or similar.

ivoanjo commented 2 years ago

For gems that employ the empty Makefile strategy for platforms that are not supported, having make would be enough.

For gems going deeper into ffi, having a few more build tools would be useful, although the tradeoff in terms of added size on the docker images may not work out. I somewhat worry it may drive people to create new, "slimmer" images, that then start the cycle again of not having make 🤣

headius commented 2 years ago

Ahh now I see, so you are suggesting we add make just for those gems that fake out the makefile to fall back on a prebuilt JRuby extension. That seems like a reasonable and small enough change. PR?

ivoanjo commented 2 years ago

Sure! I'll whip up a PR -- might take a few days since I'm going to be traveling next week but I shall deliver!

ivoanjo commented 1 year ago

@headius opened the PR in #82 :)