如何在OS X更新后更新RbConfig

时间:2016-02-22 22:46:22

标签: ruby macos

我正在尝试使用RbConfig::CONFIG来获取有关OS X当前版本的信息。在使用Ruby的机器上,该机器在Yosemite(Darwin 14)上编译但随后升级为El Capitan(Darwin 15), uname -a仍然会报告达尔文14的版本。

我可以切换到解析RbConfig::CONFIG的返回值,但我宁愿使用Ruby原生解决方案。有没有办法更新RbConfig::CONFIG而无需重新编译和重新安装Ruby?

更新

我发现在configure脚本中列出了configure中的所有键。似乎每个值都在CONFIG内分配。我还看不到键值对列表如何序列化为config.inc.php常量。

2 个答案:

答案 0 :(得分:1)

这取决于您的ruby安装。

您使用Apple提供的Ruby.Framework。

你无事可做。
我检查了iMac(2013年初)和MBP(2015年初):

$ rbenv local system
$ rbenv rehash
$ irb
> RbConfig::CONFIG['host']
   => "x86_64-apple-darwin15"

实际上有rbconfig.rb个文件包含以下设置:

grep "darwin15" /System/Library/Frameworks/Ruby.framework/Versions/Current/usr/lib/ruby/2.0.0/universal-darwin15/rbconfig.rb
  TOPDIR = File.dirname(__FILE__).chomp!("/lib/ruby/2.0.0/universal-darwin15")
  CONFIG["arch"] = "universal-darwin15"
  CONFIG["target_os"] = "darwin15"
  CONFIG["target"] = "universal-apple-darwin15"
  CONFIG["host_os"] = "darwin15"
  CONFIG["host"] = "x86_64-apple-darwin15"
  CONFIG["build_os"] = "darwin15"
  CONFIG["build"] = "x86_64-apple-darwin15"

由于System Intregrity Protection很好,您无法对其进行修改。

您使用从rvm,rbenv等处获得的已下载和编译的ruby版本。

我无法提供通用解决方案,但这是我所做的(我使用rbenv)。

$ rbenv local 2.2.3

$ rbenv rehash

# What is the config?
$ ruby -e 'p RbConfig::CONFIG["host"]'
"x86_64-apple-darwin14.5.0"

# Where is this?
$ grep -nir "x86_64-apple-darwin14.5.0" ~/.rbenv/versions/2.2.3/lib/ruby
~/.rbenv/versions/2.2.3/lib/ruby/2.2.0/x86_64-darwin14/rbconfig.rb:191:  CONFIG["host"] = "x86_64-apple-darwin14.5.0"
~/.rbenv/versions/2.2.3/lib/ruby/2.2.0/x86_64-darwin14/rbconfig.rb:198:  CONFIG["build"] = "x86_64-apple-darwin14.5.0"

# Change the CONFIG values according to your needs
$ vi ~/.rbenv/versions/2.2.3/lib/ruby/2.2.0/x86_64-darwin14/rbconfig.rb

$ ruby -e 'p RbConfig::CONFIG["host"]'
"x86_64-apple-darwin42"

希望它有所帮助。

答案 1 :(得分:0)

那就是RbConfig::CONFIG['host']应该返回AFAIC的内容:构建ruby的操作系统版本,而不是当前的操作系统版本。如果您认为它有意义:可能有库或某些内部组件需要确保您当前的ruby版本与某些库版本相关联,所以如果您使用v15但是它在构建时当前不支持某些内容是(并且是)版本v14所以你已经在早期版本上构建它的事实将使其工作,无论操作系统升级,当然这只是一种可能的情况,并不是说它对于这个特定情况实际上是正确的。如果你改变它并强制ruby报告它是在你当前的操作系统上构建的(或者与其他一些链接到它的库版本),那么你可能肯定会破坏它。

为什么不像你说的那样使用uname -r创建一个简单的函数呢?这样做会很好,我知道这不是你要求的确切答案,但我已经暴露了我的推理:

require "open3"

def detect_os
  cmd = "uname -r"

  Open3.popen3 cmd do |stdin, stdout, stderr, wait_thr|
    error = stderr.read 
    raise StandardError.new("Error while detecting OS: '#{error}'") unless error.empty?
    stdout.read
  end
end

puts detect_os