Gem RubyGem 的 Native 依赖之痛

zlx_star · 2015年07月12日 · 最后由 zlx_star 回复于 2015年07月14日 · 2813 次阅读

我们平时安装 Gem 经常会碰到 Failed to build gem native extension 的问题

StackOverflow 上面关于这个问题的讨论有 2500+ http://stackoverflow.com/search?q=Failed+to+build+gem+native+extension

那么:

  1. RubyGem 官方是如何处理这种 Native 依赖的,完全交由 Gem 开发者自己处理还是有什么规范指导?
  2. 大家平时又是如何处理这种依赖的?

欢迎大家讨论和建议

http://guides.rubygems.org/gems-with-extensions/

我见过的最常见问题是没装编译工具,除了安装编译工具也没别的办法了。

Nokogiri 为了方便处理依赖把 c 库和 java 库源码打包到 gem 里。

#1 楼 @rei 我也翻到了这篇文章,这里提供了编写 C 库的方法

对于依赖的解决,看来是开发者智者见智的问题了,最简单粗暴的就是 abort "missing malloc()" 抱怨一下,让使用者来解决了

Nokogiri 还算是比较好的, 还有很多数据库的 adapter 也是 Native 依赖大头

有人做了这个东西 https://github.com/voxik/gem-nice-install

挺好的一个尝试,不过目前只支持 Fedora

gem 和系统之间的依赖确实蛋疼,就像早期的 gem 依赖了什么系统库连说明也没有,只有自己去摸索;

如果 rubygem 里面可以声明系统依赖自然是极好的 XD,就像 gemspec 声明对其它 gem 包的依赖

#4 楼 @PlayMonkey 现在 gemspec 里面可以声明系统依赖 http://guides.rubygems.org/specification-reference/#requirements

不过好像只是提醒一下。

#5 楼 @rei It's simply information for the user. 看来只是提供信息,不过也好过没有了 XD

这个是没有办法的,很多语言都支持 ffi 复用 c library,多安装几个动态链接库和开发节省的时间根本不能比。

只能怪 rubygems 没有下载本地库的机制,下载好 ruby 文件后再下载本地库,npm 好像已经做到了。

#7 楼 @nouse 真的咩? npm 连递归依赖都没做到...

我有一个思路是找到 GEM 的依赖库,用本机对应的包管理工具安装,这个过程在 Gem install 的时候自动完成。

Gem plugin: https://github.com/voxik/gem-nice-install Ohai: https://github.com/chef/ohai

根据上面这两个工具,可行性还是比较高的,只是目前没有好办法可以自动找到依赖库,需要用配置文件配置。

#8 楼 @luikore 看了一下 npm 本身只支持 post-install 脚本 ( https://docs.npmjs.com/misc/scripts ),下载不同平台的依赖库是用 bin-wrapper 这个 library 实现的。带来的隐患是因为大家把本地依赖库都放在了 github 上,如果 github 挂了,npm 安装就会受影响。

而 rubygems 本身只支持 post_install_message,结果除了打印 httparty 之外没什么 egg 用。rubygems 本身也没有改进计划,比如 http://stackoverflow.com/questions/14395992/how-to-execute-a-script-while-gem-installation

#10 楼 @nouse

是的 post install script 都是用 extconf.rb hack 的, 我也写过...

感觉 bin-wrapper 和用 rake compiler 产生 fat gem 是一样的? 发布 bin 往往享受不到平台硬件加速, 某些东西本地编译一次可以快好几倍...

#10 楼 @nouse #11 楼 @luikore 听大牛讨论问题,总是有收获

需要 登录 后方可回复, 如果你还没有账号请 注册新账号