C 如何将JSON扩展链接到正确的Ruby版本?

C 如何将JSON扩展链接到正确的Ruby版本?,c,ruby,C,Ruby,如果我安装Ruby 2.1.6(或2.2.2等)并尝试要求使用“json”,我会得到一个segfault。我听说“您的json扩展链接到ruby 2.0.0,而不是ruby 2.1.6。” 我用安装了Ruby版本,但我不太了解编译Ruby的细节 如何让这个扩展链接到正确的Ruby版本 澄清 这是一个关于编译Ruby可执行文件的C源代码的问题。回答这个问题需要C语言知识,而不仅仅是Ruby知识;这就是为什么我用两种语言标记它 我真正的目标是能够使用最新的Ruby版本(目前为2.2.2)rails服

如果我安装Ruby 2.1.6(或2.2.2等)并尝试
要求使用“json”
,我会得到一个segfault。我听说“您的json扩展链接到ruby 2.0.0,而不是ruby 2.1.6。”

我用安装了Ruby版本,但我不太了解编译Ruby的细节

如何让这个扩展链接到正确的Ruby版本

澄清 这是一个关于编译Ruby可执行文件的C源代码的问题。回答这个问题需要C语言知识,而不仅仅是Ruby知识;这就是为什么我用两种语言标记它

我真正的目标是能够使用最新的Ruby版本(目前为2.2.2)
rails服务器
。执行
require'json'
有时会触发segfault,但
rails
总是会触发

更新 我在找人陪我解决这个问题


我已经尝试将我的整个
~/.rubies
文件夹移动到
~/.old_rubies
并从头开始安装ruby 2.2.2。我尝试卸载它允许我卸载的每个JSON gem(尽管它不允许我删除默认gem)。有时
irb;要求使用“json”
是可行的,但启动rails服务器时总是会出现故障。

听起来像是在处理一个典型的依赖地狱问题

第一件事:我们需要隔离您的环境。我们不希望您的操作系统安装的Ruby或其gems干扰您的项目安装的Ruby

安装以下工具:

  • 安装
    ruby安装
  • 安装
    chruby
  • 安装
    gem_home
并遵循各自的自制说明

现在安装您喜欢的Ruby:

ruby-install ruby 2.2.2
chruby 2.2.2
导航到您的项目目录:

cd ~/projects/operation-snugglepants
gem_home .
切换到您喜欢的Ruby:

ruby-install ruby 2.2.2
chruby 2.2.2
然后确保您没有被系统抢先:

which ruby
应该给你一条像这样的路

~/.rubies/ruby-2.2.2/bin/ruby
并验证其版本是否正确:

ruby -v
ruby 2.2.2p95 ...
太好了,现在你得到了正确的红宝石。让我们确保你有正确的宝石。将gem安装目标设置为项目的目录:

cd ~/projects/operation-snugglepants
gem_home .
并安装绑定器:

gem install bundler
然后安装gems:

bundle install
完成后,现在
捆绑rails服务器
并验证其是否正常工作:

bundle exec rails server
=> Booting WEBrick
=> Rails 4.2.0 application starting in development on http://localhost:3000
始终确保已将系统依赖项(SystemRuby和SystemGems)与应用程序依赖项(ApplicationRuby和ApplicationGems)隔离开来。如果可能的话,千万不要把两者混在一起

我还使用了一个在我的shell启动时加载一些别名的工具来“跳转”到我的Ruby项目特定的环境中,以使事情更容易处理--可以随意滑动它

什么有效 帮我修好了,但我想详细说明一下我做了什么

首先,我卸载了所有版本的
json
gem,除了默认版本,并安装了一个更新的版本。下一次运行
rails s
时,我看到segfault是在尝试要求
nokogiri
时发生的。我想,“也许它是任何带有C扩展名的宝石?”

我的猜测是它们都需要重新编译,但是
bundle install
$GEM_PATH
的其他地方找到了旧版本,因此没有在
$GEM_HOME
中安装/重新编译新版本

因此,我按照John的指示,在项目文件夹中运行了
gem_home.
,然后使用以下Ruby脚本卸载了所有gem:

`gem list --no-versions`.split("\n").each do |gem|
  `gem list -d #{gem}`.gsub(/Installed at(.*):.*/).each do |dir|
    dir = dir.gsub(/Installed at(.*): /,'').gsub("\n", '')
    system "gem uninstall #{gem} -aIx -i #{dir}"
  end  
end
之后,我运行了
bundle install
,因为我已经完成了
gem\u home.
,所以将新版本放在
我的项目文件夹/.gem/ruby/2.2

然后,当我运行rails s时,它没有出错

总之,yaaaaay:D

更新:我想我已经发现了根本原因 我想我已经找到了根本原因。我可以再次得到这样的错误:

  • 安装一个新版本的Ruby(或者将gem dir重命名为一个版本,例如,
    ~/.gem/Ruby/2.2.0
    2.2.0\u inactive
  • cd my_项目
    chruby 2.2.0
  • bundle安装
    #=>错误,没有这样的gem
  • gem安装bundler
    #=>工作正常
  • 哪个bundle
    #=>哦,什么,它是
    /usr/bin/bundle
  • 捆绑安装
    #这将造成悲伤
为什么??由于这个Ruby还没有宝石,
哪个bundle
指向系统Ruby附带的
/usr/bin/bundle
。任何
bundle安装
为编译代码的gems在尝试使用不同的Ruby版本时都可能导致segfaults

相反,如果在运行
bundle install
之前,I
chruby 2.2.2
哪个bundle
提供了
~/.gem/ruby/2.1.2/bin/bundle
,并且
bundle install
工作正常


以下是我为防止将来出现这种情况所做的工作:在
/usr/bin/bundle
处编辑Ruby脚本,以
发出警告并退出
。对于
/usr/bin/bundler
/usr/bin/rails
也一样,这是一个很好的衡量标准。

为什么要添加
C
标签?你能发布你的“gem env”吗?@MohitJain可能是因为Ruby(MRI)是用C编写的,而且在纯Ruby代码中,如果Ruby的C部分没有bug,通常都无法得到segfaults,或者C代码链接到的其他二进制代码位。@Ajedi32谢谢。这是有道理的。抱歉我的无知。@MohitJain安装MRI Ruby涉及从C代码编译Ruby可执行文件。“链接”不是在Ruby中做的事情,但这种特殊的链接是Ruby所需要的。所以这个问题实际上是C和Ruby的交叉点,谢谢。遗憾的是,我在尝试
捆绑execrails服务器时仍然会遇到segfault。在那之前一切看起来都很好,你呢