Rails5旧项目bundle更新/安装失败及Ruby版本安装报错求助
Rails 5旧项目重启遇到的三类问题及解决方案
问题1:ovirt-engine-sdk 4.4.1原生扩展构建失败
运行bundle update或单独执行gem install ovirt-engine-sdk -v '4.4.1'时,报错error: use of undeclared identifier 'rb_cData',完整日志如下:
gem install ovirt-engine-sdk -v '4.4.1' --source 'https://rubygems.org/' [(3.2.2)] Building native extensions. This could take a while... ERROR: Error installing ovirt-engine-sdk: ERROR: Failed to build gem native extension. current directory: /Users/nelly/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/ovirt-engine-sdk-4.4.1/ext/ovirtsdk4c /Users/nelly/.rbenv/versions/3.2.2/bin/ruby extconf.rb checking for xml2-config... yes checking for curl-config... yes creating Makefile current directory: /Users/nelly/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/ovirt-engine-sdk-4.4.1/ext/ovirtsdk4c make DESTDIR\= sitearchdir\=./.gem.20230416-42051-ofowhj sitelibdir\=./.gem.20230416-42051-ofowhj clean current directory: /Users/nelly/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/ovirt-engine-sdk-4.4.1/ext/ovirtsdk4c make DESTDIR\= sitearchdir\=./.gem.20230416-42051-ofowhj sitelibdir\=./.gem.20230416-42051-ofowhj compiling ov_error.c compiling ov_http_client.c ov_http_client.c:216:29: warning: excess elements in array initializer [-Wexcess-initializers] .reserved = { NULL, NULL } ^~~~ /Library/Developer/CommandLineTools/usr/lib/clang/14.0.0/include/stddef.h:89:16: note: expanded from macro 'NULL' # define NULL ((void*)0) ^~~~~~~~~~ ov_http_client.c:272:39: warning: implicit conversion loses integer precision: 'unsigned long' to 'int' [-Wshorten-64-to-32] count = INT2NUM(context_ptr->size * context_ptr->nmemb); ~~~~~~~ ~~~~~~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~ ov_http_client.c:392:33: warning: comparison of integers of different signs: 'long' and 'size_t' (aka 'unsigned long') [-Wsign-compare] while (pointer - buffer < length && isspace(*pointer)) { ~~~~~~~~~~~~~~~~ ^ ~~~~~~ ov_http_client.c:651:18: warning: implicit conversion loses integer precision: 'long' to 'int' [-Wshorten-64-to-32] ptr->limit = connections; ~ ^~~~~~~~~~~ ov_http_client.c:845:71: warning: implicit conversion loses integer precision: 'long' to 'int' [-Wshorten-64-to-32] context_ptr->code = curl_multi_wait(context_ptr->handle, NULL, 0, timeout, NULL); ~~~~~~~~~~~~~~~ ^~~~~~~ ov_http_client.c:1001:47: warning: incompatible function pointer types passing 'int (VALUE, VALUE, struct curl_slist **)' (aka 'int (unsigned long, unsigned long, struct curl_slist **)') to parameter of type 'int (*)(VALUE, VALUE, VALUE)' (aka 'int (*)(unsigned long, unsigned long, unsigned long)') [-Wincompatible-function-pointer-types] rb_hash_foreach(request_ptr->headers, ov_http_client_add_header, (VALUE) headers); ^~~~~~~~~~~~~~~~~~~~~~~~~ /Users/nelly/.rbenv/versions/3.2.2/include/ruby-3.2.0/ruby/internal/intern/hash.h:83:40: note: passing argument to parameter 'func' here void rb_hash_foreach(VALUE hash, int (*func)(VALUE key, VALUE val, VALUE arg), VALUE arg); ^ ov_http_client.c:1092:34: warning: comparison of integers of different signs: 'size_t' (aka 'unsigned long') and 'int' [-Wsign-compare] if (RHASH_SIZE(ptr->pending) < ptr->limit) { ~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~ ov_http_client.c:1118:71: warning: comparison of integers of different signs: 'size_t' (aka 'unsigned long') and 'int' [-Wsign-compare] while (RARRAY_LEN(ptr->queue) > 0 && RHASH_SIZE(ptr->pending) < ptr->limit) { ~~~~~~~~~~~~~~~~~~~~~~~~ ^ ~~~~~~~~~~ 8 warnings generated. compiling ov_http_request.c ov_http_request.c:75:29: warning: excess elements in array initializer [-Wexcess-initializers] .reserved = { NULL, NULL } ^~~~ /Library/Developer/CommandLineTools/usr/lib/clang/14.0.0/include/stddef.h:89:16: note: expanded from macro 'NULL' # define NULL ((void*)0) ^~~~~~~~~~ ov_http_request.c:347:77: error: use of undeclared identifier 'rb_cData' ov_http_request_class = rb_define_class_under(ov_module, "HttpRequest", rb_cData); ^ 1 warning and 1 error generated. make: *** [ov_http_request.o] Error 1 make failed, exit code 2 Gem files will remain installed in /Users/nelly/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/gems/ovirt-engine-sdk-4.4.1 for inspection. Results logged to /Users/nelly/.rbenv/versions/3.2.2/lib/ruby/gems/3.2.0/extensions/arm64-darwin-21/3.2.0/ovirt-engine-sdk-4.4.1/gem_make.out
原因及解决办法
rb_cData是Ruby 2.x的内置常量,Ruby 3.0+已移除该定义,改用rb_cObject替代。ovirt-engine-sdk 4.4.1未适配Ruby 3.x,有两种解决路径:
- 降级Ruby到2.7.x版本(Rails 5.2支持的最高Ruby版本);
- 升级ovirt-engine-sdk到4.5.0及以上版本(该版本已修复Ruby 3.x兼容性问题),修改Gemfile中版本号为
gem 'ovirt-engine-sdk', '>= 4.5.0'后重新执行bundle install。
问题2:minitest-5.13.0与Ruby 3.2.2版本不兼容
运行bundle install时提示:minitest-5.13.0 requires ruby version ~> 2.2, which is incompatible with the current version, ruby 3.2.2p53
原因及解决办法
minitest-5.13.0的版本约束仅支持Ruby 2.2~2.7,Ruby 3.x需要更高版本的minitest。解决步骤:
- 修改Gemfile,添加
gem 'minitest', '>= 5.16.0'(该版本兼容Ruby 3.x); - 执行
bundle update minitest更新依赖; - 重新运行
bundle install。
或者直接降级Ruby到2.7.x,保持minitest-5.13.0版本正常使用。
问题3:安装Ruby 2.4.4时构建失败
执行rbenv install 2.4.4报错:error: implicit declaration of function 'ffi_prep_closure' is invalid in C99,完整日志如下:
rbenv install 2.4.4 [(3.2.2)] To follow progress, use 'tail -f /var/folders/bh/wbvn20493_s066frg6c2wwx00000gn/T/ruby-build.20230426171026.41848.log' or pass --verbose Downloading openssl-1.1.1t.tar.gz... -> https://dqw8nmjcqpjn7.cloudfront.net/8dee9b24bdb1dcbf0c3d1e9b02fb8f6bf22165e807f45adeb7c9677536859d3b Installing openssl-1.1.1t... Installed openssl-1.1.1t to /Users/nelly/.rbenv/versions/2.4.4 Downloading ruby-2.4.4.tar.bz2... -> https://cache.ruby-lang.org/pub/ruby/2.4/ruby-2.4.4.tar.bz2 Installing ruby-2.4.4... WARNING: ruby-2.4.4 is past its end of life and is now unsupported. It no longer receives bug fixes or critical security updates. ruby-build: using readline from homebrew ruby-build: using libyaml from homebrew BUILD FAILED (macOS 12.6.5 using ruby-build 20230330) Inspect or clean up the working tree at /var/folders/bh/wbvn20493_s066frg6c2wwx00000gn/T/ruby-build.20230426171026.41848.J8bKnO Results logged to /var/folders/bh/wbvn20493_s066frg6c2wwx00000gn/T/ruby-build.20230426171026.41848.log Last 10 log lines: ../.././include/ruby/ruby.h:1753:56: note: expanded from macro 'rb_intern' __extension__ (RUBY_CONST_ID_CACHE((ID), (str))) : \ ^ closure.c:263:14: error: implicit declaration of function 'ffi_prep_closure' is invalid in C99 [-Werror,-Wimplicit-function-declaration] result = ffi_prep_closure(pcl, cif, callback, (void *)self); ^ 6 warnings and 1 error generated. make[2]: *** [closure.o] Error 1 make[1]: *** [ext/fiddle/all] Error 2 make: *** [build-ext] Error 2
原因及解决办法
Ruby 2.4.4与新版macOS(12.6.5)的libffi库不兼容,ffi_prep_closure函数的声明在新版libffi中已变更。解决办法:
- 安装旧版本libffi:
brew install libffi@3.3; - 指定libffi路径安装Ruby:
RUBY_CONFIGURE_OPTS="--with-libffi-dir=$(brew --prefix libffi@3.3)" rbenv install 2.4.4
- 更推荐的方案:放弃Ruby 2.4.4,改用Ruby 2.7.x(Rails 5.2支持的最高版本,兼容性更好,且仍有安全更新支持)。
项目Gemfile参考
source 'https://rubygems.org' ruby '3.2.2' gem 'bootsnap', require: false gem 'jbuilder', '~> 2.0' gem 'puma' gem 'rails', '5.2.1' gem 'redis' gem 'autoprefixer-rails' gem 'bootstrap', '~> 4.1.3' gem 'sprockets-rails', :require => 'sprockets/railtie' gem 'font-awesome-sass', '~> 5.0.9' gem 'sass-rails', '>= 3.2' gem 'simple_form' gem 'uglifier' gem 'webpacker' gem 'jquery-rails' gem 'mail_form' gem 'meta-tags' gem 'devise' gem 'fog' gem 'carrierwave', '~> 1.2', '>= 1.2.3' #gem 'mimemagic' gem 'file_validators' gem 'react-rails' gem 'photoswipe-rails' gem 'faker', '~> 1.9', '>= 1.9.1' gem 'geocoder' gem "recaptcha", require: "recaptcha/rails" gem 'sitemap_generator' group :development do gem 'web-console', '>= 3.3.0' #gem 'pg', '~> 1.4', '>= 1.4.6' end group :development, :test do gem 'rspec-rails', '~> 3.7' gem 'launchy' gem "chromedriver-helper" gem 'selenium-webdriver' gem 'database_cleaner' gem 'shoulda-matchers', '~> 3.1' gem 'capybara' #gem 'capybara-webkit' gem 'rails-controller-testing' gem 'pry-byebug' gem 'pry-rails' gem 'listen', '~> 3.0.5' gem 'spring' gem 'spring-watcher-listen', '~> 2.0.0' gem 'dotenv-rails' end
内容的提问来源于stack exchange,提问作者marie
相关产品推荐
相关产品推荐

