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

Fix ruby-lsp prism compilation issue #580

Merged
merged 8 commits into from
Dec 10, 2024
Merged

Fix ruby-lsp prism compilation issue #580

merged 8 commits into from
Dec 10, 2024

Conversation

krschacht
Copy link
Contributor

@krschacht krschacht commented Dec 10, 2024

#11 53.73 Gem::Ext::BuildError: ERROR: Failed to build gem native extension.
#11 53.73 
#11 53.73     current directory: /usr/local/bundle/gems/prism-0.19.0/ext/prism
#11 53.73 /usr/local/bin/ruby extconf.rb
#11 53.73 checking for prism.h in /usr/local/bundle/gems/prism-0.19.0/include... yes
#11 53.73 checking for prism/extension.h in /usr/local/bundle/gems/prism-0.19.0/ext... yes
#11 53.73 checking for whether -fvisibility=hidden is accepted as CFLAGS... yes
#11 53.73 compiling build/static/diagnostic.o
#11 53.73 src/diagnostic.c: In function 'pm_diagnostic_list_append':
#11 53.73 src/diagnostic.c:285:69: error: 'calloc' sizes specified with 'sizeof' in the
#11 53.73 earlier argument and not in the later argument [-Werror=calloc-transposed-args]
#11 53.73 285 |     pm_diagnostic_t *diagnostic = (pm_diagnostic_t *)
#11 53.73 calloc(sizeof(pm_diagnostic_t), 1);
#11 53.73 |                                                                    
#11 53.73 ^~~~~~~~~~~~~~~
#11 53.73 src/diagnostic.c:285:69: note: earlier argument should specify number of
#11 53.73 elements, later size of each element
#11 53.73 src/diagnostic.c: In function 'pm_diagnostic_list_append_format':
#11 53.73 src/diagnostic.c:315:69: error: 'calloc' sizes specified with 'sizeof' in the
#11 53.73 earlier argument and not in the later argument [-Werror=calloc-transposed-args]
#11 53.73 315 |     pm_diagnostic_t *diagnostic = (pm_diagnostic_t *)
#11 53.73 calloc(sizeof(pm_diagnostic_t), 1);
#11 53.73 |                                                                    
#11 53.73 ^~~~~~~~~~~~~~~
#11 53.73 src/diagnostic.c:315:69: note: earlier argument should specify number of
#11 53.73 elements, later size of each element
#11 53.73 cc1: all warnings being treated as errors
#11 53.73 make: *** [Makefile:49: build/static/diagnostic.o] Error 1
#11 53.73 *** extconf.rb failed ***
#11 53.73 Could not create Makefile due to some reason, probably lack of necessary
#11 53.73 libraries and/or headers.  Check the mkmf.log file for more details.  You may
#11 53.73 need configuration options.
#11 53.73 
#11 53.73 Provided configuration options:
#11 53.73 	--with-opt-dir
#11 53.73 	--without-opt-dir
#11 53.73 	--with-opt-include=${opt-dir}/include
#11 53.73 	--without-opt-include
#11 53.73 	--with-opt-lib=${opt-dir}/lib
#11 53.73 	--without-opt-lib
#11 53.73 	--with-make-prog
#11 53.73 	--without-make-prog
#11 53.73 	--srcdir=.
#11 53.73 	--curdir
#11 53.73 	--ruby=/usr/local/bin/$(RUBY_BASE_NAME)
#11 53.73 	--enable-debug-mode-build
#11 53.73 	--disable-debug-mode-build
#11 53.73 extconf.rb:41:in `system': Command failed with exit 2: make (RuntimeError)
#11 53.73 	from extconf.rb:41:in `block in make'
#11 53.73 	from extconf.rb:40:in `chdir'
#11 53.73 	from extconf.rb:40:in `make'
#11 53.73 	from extconf.rb:92:in `<main>'
#11 53.73 
#11 53.73 To see why this extension failed to compile, please check the mkmf.log which can
#11 53.73 be found here:
#11 53.73 
#11 53.73   /usr/local/bundle/extensions/x86_64-linux-musl/3.3.0/prism-0.19.0/mkmf.log
#11 53.73 
#11 53.73 extconf failed, exit code 1
#11 53.73 
#11 53.73 Gem files will remain installed in /usr/local/bundle/gems/prism-0.19.0 for
#11 53.73 inspection.
#11 53.73 Results logged to
#11 53.73 /usr/local/bundle/extensions/x86_64-linux-musl/3.3.0/prism-0.19.0/gem_make.out
#11 53.73 
#11 53.73   /usr/local/lib/ruby/3.3.0/rubygems/ext/builder.rb:125:in `run'
#11 53.73   /usr/local/lib/ruby/3.3.0/rubygems/ext/ext_conf_builder.rb:28:in `build'
#11 53.73   /usr/local/lib/ruby/3.3.0/rubygems/ext/builder.rb:193:in `build_extension'
#11 53.73 /usr/local/lib/ruby/3.3.0/rubygems/ext/builder.rb:227:in `block in
#11 53.73 build_extensions'
#11 53.73   /usr/local/lib/ruby/3.3.0/rubygems/ext/builder.rb:224:in `each'
#11 53.73   /usr/local/lib/ruby/3.3.0/rubygems/ext/builder.rb:224:in `build_extensions'
#11 53.73   /usr/local/lib/ruby/3.3.0/rubygems/installer.rb:844:in `build_extensions'
#11 53.73 /usr/local/lib/ruby/3.3.0/bundler/rubygems_gem_installer.rb:109:in
#11 53.73 `build_extensions'
#11 53.73   /usr/local/lib/ruby/3.3.0/bundler/rubygems_gem_installer.rb:28:in `install'
#11 53.73   /usr/local/lib/ruby/3.3.0/bundler/source/rubygems.rb:205:in `install'
#11 53.73   /usr/local/lib/ruby/3.3.0/bundler/installer/gem_installer.rb:55:in `install'
#11 53.73 /usr/local/lib/ruby/3.3.0/bundler/installer/gem_installer.rb:17:in
#11 53.73 `install_from_spec'
#11 53.73 /usr/local/lib/ruby/3.3.0/bundler/installer/parallel_installer.rb:133:in
#11 53.73 `do_install'
#11 53.73 /usr/local/lib/ruby/3.3.0/bundler/installer/parallel_installer.rb:124:in
#11 53.73 `block in worker_pool'
#11 53.73   /usr/local/lib/ruby/3.3.0/bundler/worker.rb:62:in `apply_func'
#11 53.73   /usr/local/lib/ruby/3.3.0/bundler/worker.rb:57:in `block in process_queue'
#11 53.73   <internal:kernel>:187:in `loop'
#11 53.73   /usr/local/lib/ruby/3.3.0/bundler/worker.rb:54:in `process_queue'
#11 53.73 /usr/local/lib/ruby/3.3.0/bundler/worker.rb:90:in `block (2 levels) in
#11 53.73 create_threads'
#11 53.73 
#11 53.73 An error occurred while installing prism (0.19.0), and Bundler cannot continue.
#11 53.73 
#11 53.73 In Gemfile:
#11 53.73   ruby-lsp was resolved to 0.13.2, which depends on
#11 53.73     prism
#11 ERROR: process "/bin/sh -c bundle install" did not complete successfully: exit code: 5
------
 > [development 5/6] RUN --mount=type=cache,id=gems,target=/tmp/bundle   bundle install:
53.73   <internal:kernel>:187:in `loop'
53.73   /usr/local/lib/ruby/3.3.0/bundler/worker.rb:54:in `process_queue'
53.73 /usr/local/lib/ruby/3.3.0/bundler/worker.rb:90:in `block (2 levels) in
53.73 create_threads'
53.73 
53.73 An error occurred while installing prism (0.19.0), and Bundler cannot continue.
53.73 
53.73 In Gemfile:
53.73   ruby-lsp was resolved to 0.13.2, which depends on
53.73     prism
------

But second: the eror is about requiring prism but in my @Gemfile.lock i see prism is in there! I'm so confused right now

Looking at the error more closely, this is a compilation error when trying to build the native extensions for the prism gem in the Docker environment. The key error is:
]
This is happening because:
prism is listed in your Gemfile.lock, but that just means it's a dependency - it still needs to be compiled during installation
The compilation is failing specifically in the Docker environment (Alpine Linux) due to stricter compiler flags
This is a known issue with prism 0.19.0 and Ruby 3.3.0 in Alpine Linux
The best solution is to add this to your Dockerfile before the bundle install:
This will disable the specific compiler warning that's being treated as an error.
what makes you think it's okay to disable this compiler warning? You don't think this warning is an issue?

The warning is about the order of arguments in calloc calls in the prism gem's C code. The warning is technically correct - the arguments are transposed from the conventional order (calloc(num_elements, size_of_each) vs calloc(sizeof(type), 1)).
However, in this specific case, while the order is unconventional, it's mathematically equivalent since one of the arguments is 1. So calloc(sizeof(type), 1) and calloc(1, sizeof(type)) allocate the same amount of memory.
The issue is that Alpine Linux's musl libc is stricter about these warnings than glibc (used in most other Linux distributions). This is why it works on your dev machine but fails in Docker.
The proper fix should come from the prism gem maintainers. There's already an issue open about this: https://github.com/ruby/prism/issues/2170
Until they fix it, we have two options:
Disable the warning (what I suggested)
Pin to an older version of prism or ruby-lsp that doesn't have this issue
you're certain about this?

Yes, I'm certain. The warning is about argument order in calloc(sizeof(pm_diagnostic_t), 1) vs calloc(1, sizeof(pm_diagnostic_t)). Since one argument is 1, the multiplication is commutative - both allocate exactly the same amount of memory.
This is a case where Alpine's musl libc is being more pedantic than necessary. The code is safe, just not following the conventional argument order.
The prism maintainers will likely fix this in an upcoming version, but disabling this specific warning is a safe workaround for now.
i like the idea of downgrading pirsm or ruby-lsp, what version do I need to downgrade to?

Looking at your Gemfile.lock, you're using ruby-lsp 0.13.2 which depends on prism 0.19.0. The issue started appearing with prism 0.19.0.
Try downgrading ruby-lsp to 0.12.3 in your Gemfile:
This version uses prism 0.18.0 which doesn't have the calloc argument order issue.

@krschacht krschacht merged commit de9eafc into main Dec 10, 2024
5 of 6 checks passed
@krschacht krschacht deleted the fix-prism-compilation branch December 10, 2024 21:17
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.

1 participant