Ruby项目bundle install时unf_ext 0.0.9原生扩展安装失败求助
问题描述
在基于以下Gemfile配置的Ruby项目中执行bundle install时遇到编译错误:
ruby '2.3.1' source 'http://www.rubygems.org' gem 'aws-flow', '~> 2.4.0' gem 'aws-sdk-core', '~> 3.65', '>= 3.65.1' gem 'aws-sdk', '~> 3.0', '>= 3.0.1' gem 'nokogiri', '~> 1.10.10' gem 'activerecord', '~> 5.2', '>= 5.2.3' gem 'sqlite3', '~> 1.3', '= 1.3.9' gem 'rubyzip', '~> 1.2', '>= 1.2.3' gem 'mechanize', '~> 2.7', '>= 2.7.5' gem 'slack-notifier', '~> 1.5', '>= 1.5.1' gem 'minitest', '~> 5.8.4' gem 'connection_pool', '~> 2.2.5' gem 'httparty', '~> 0.19.1' gem 'webrick', '~> 1.7.0' gem 'net-http-persistent', '= 4.0.1'
错误发生在安装unf_ext(版本0.0.9)这个依赖gem时,具体报错信息如下:
Don't run Bundler as root. Bundler can ask for sudo if it is needed, and installing your bundle as root will break this application for all non-root users on this machine. Fetching gem metadata from http://www.rubygems.org/ Fetching version metadata from http://www.rubygems.org/ Fetching dependency metadata from http://www.rubygems.org/ Resolving dependencies.............................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................. Using concurrent-ruby 1.2.2 Using minitest 5.8.5 Using thread_safe 0.3.6 Using arel 9.0.0 Using aws-eventstream 1.2.0 Using json 1.8.6 Using mini_portile2 2.4.0 Using lru_redux 0.8.4 Using aws-partitions 1.848.0 Using jmespath 1.6.2 Using aws-sigv2 1.1.0 Using connection_pool 2.2.5 Installing unf_ext 0.0.9 with native extensions Gem::Ext::BuildError: ERROR: Failed to build gem native extension. current directory: /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/unf_ext-0.0.9/ext/unf_ext /opt/rubies/ruby-2.3.1/bin/ruby -r ./siteconf20231113-2866-7e5i1z.rb extconf.rb checking for main() in -lstdc++... yes creating Makefile To see why this extension failed to compile, please check the mkmf.log which can be found here: /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/extensions/x86_64-linux/2.3.0-static/unf_ext-0.0.9/mkmf.log current directory: /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/unf_ext-0.0.9/ext/unf_ext make "DESTDIR=" clean current directory: /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/unf_ext-0.0.9/ext/unf_ext make "DESTDIR=" compiling unf.cc cc1plus: warning: command line option ‘-Wdeclaration-after-statement’ is valid for C/ObjC but not for C++ [enabled by default] cc1plus: warning: command line option ‘-Wimplicit-function-declaration’ is valid for C/ObjC but not for C++ [enabled by default] unf.cc:39:3: sorry, unimplemented: non-trivial designated initializers not supported }; ^ unf.cc:39:3: sorry, unimplemented: non-trivial designated initializers not supported make: *** [unf.o] Error 1 make failed, exit code 2 Gem files will remain installed in /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/gems/unf_ext-0.0.9 for inspection. Results logged to /opt/rubies/ruby-2.3.1/lib/ruby/gems/2.3.0/extensions/x86_64-linux/2.3.0-static/unf_ext-0.0.9/gem_make.out Using mime-types-data 3.2023.1003 Using multi_xml 0.6.0 Using net-http-digest_auth 1.4.1 Using ntlm-http 0.1.1 Using webrick 1.7.0 Using webrobots 0.1.2 Using rubyzip 1.3.0 Using slack-notifier 1.5.1 Using sqlite3 1.3.9 Using bundler 1.12.1 Using i18n 1.14.1 Using tzinfo 1.2.11 Using aws-sigv4 1.6.1 Using nokogiri 1.10.10 Using net-http-persistent 4.0.1 An error occurred while installing unf_ext (0.0.9), and Bundler cannot continue. Make sure that `gem install unf_ext -v '0.0.9'` succeeds before bundling.
未在Gemfile中显式引入unf_ext,它是其他gem的依赖,查看mkmf.log后仍无法定位问题,需要解决编译错误并确认是否需要调整gem版本。
解决方案
1. 定位unf_ext的依赖来源
执行以下命令可以追踪到哪个gem引入了unf_ext:
# 查看依赖树中unf_ext的关联 bundle list --tree | grep -B2 -A2 unf_ext
通常unf_ext是unf的依赖,而unf又被mechanize这类处理网页编码的gem引入,你的Gemfile里的mechanize (~>2.7.5)大概率是源头。
2. 解决编译错误
编译报错non-trivial designated initializers not supported的核心原因是:Ruby 2.3.1版本过于老旧,搭配的unf_ext 0.0.9代码与当前系统的高版本C++编译器不兼容。
可选修复方案:
- 方案一:锁定兼容的
unf_ext版本
在Gemfile中添加显式版本锁定,选择适配Ruby 2.3.1和旧编译器的版本,比如unf_ext 0.0.7.7:
gem 'unf_ext', '0.0.7.7'
之后重新执行bundle install。
- 方案二:临时指定低版本编译器
如果是Linux环境,安装GCC 6或更低版本并临时指定编译器:
# Debian/Ubuntu系统安装低版本编译器 sudo apt install gcc-6 g++-6 # 用指定编译器执行bundle install CC=gcc-6 CXX=g++-6 bundle install
- 方案三:升级Ruby版本(长期推荐)
Ruby 2.3.1已停止维护多年,存在安全漏洞,建议升级到2.7.x或更高的维护版本,同时调整Gemfile中相关gem的版本到兼容范围,从根本上解决依赖兼容性问题。例如:
ruby '2.7.8' # 调整相关gem版本,比如mechanize升级到~>2.8.5,aws-sdk适配新版本Ruby
3. 验证修复
执行bundle install后,若所有gem安装成功,运行项目测试功能是否正常。
内容的提问来源于stack exchange,提问作者user15980977
相关产品推荐
相关产品推荐

