C 如何将JSON扩展链接到正确的Ruby版本?
如果我安装Ruby 2.1.6(或2.2.2等)并尝试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服
要求使用“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-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
#=>错误,没有这样的gembundle安装
#=>工作正常gem安装bundler
#=>哦,什么,它是哪个bundle
/usr/bin/bundle
#这将造成悲伤捆绑安装
哪个bundle
指向系统Ruby附带的/usr/bin/bundle
。任何bundle安装
为编译代码的gems在尝试使用不同的Ruby版本时都可能导致segfaults
相反,如果在运行bundle install
之前,Ichruby 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。在那之前一切看起来都很好,你呢