【问题标题】:Ruby C extension gem doesn't compile at installationRuby C 扩展 gem 在安装时无法编译
【发布时间】:2015-04-23 09:07:41
【问题描述】:

我有一个小项目想通过 gem 分享。此扩展必须在用户系统上编译。所以必须在安装gem的时候进行编译。

我的项目很简单:

tree                                                                                                                                                                  
├── myext.gemspec
├── ext
│   └── myext
│       └── myext.c
│       └── extconf.rb
├── lib
│   ├── myext
│   └── myext.rb
├── Rakefile
└── test

我已经检查了 extconf.rb,如果我这样做了,编译工作正常

ruby extconf.rb && make

我有一个 myext.gemspec:

Gem::Specification.new do |s|
  s.name        = 'myext'
  s.version     = '0.0.1'
  s.date        = '2015-04-22'
  s.summary     = "an extension"
  s.description = "an extension that is mine"
  s.authors     = ["cedlemo"]
  require "rake" #for FileList
  s.files       = FileList['lib/*/*.{so}',
                     'lib/*.{rb}'
                    ].to_a
  s.extensions = %w(ext/myext/extconf.rb)
  s.add_development_dependency 'rake-compiler', '~> 0' 
  s.license       = 'MIT'
end

这是我的 Rakefile:

require "rubygems"
require "rake/extensiontask"

spec = Gem::Specification.load('myext.gemspec')

Rake::ExtensionTask.new "myext", spec do |ext|
  ext.lib_dir = "lib/myext"
end

当我构建我的 gem 时,一切都很好:

gem build myext.gemspec

当我安装 gem 时,我没有任何错误消息:

gem install myext-0.0.1.gem                                                                                                                                          
Building native extensions.  This could take a while...
Successfully installed myext-0.0.1
1 gem installed

我的问题是 C 代码没有编译,我没有安装任何 .so 文件:

/home/cedlemo/.gem/ruby/2.2.0/gems/myext-0.0.1/
├── ext
│   └── myext
│       ├── extconf.rb
│       └── Makefile
└── lib
    └── myext.rb

PS: 我已经阅读了很多文档(官方或博客......),每个人都在做自己的事情,所以不是很清楚,我找不到解决方案,所以不要给我发链接到 http://guides.rubygems.org/ 例如。

【问题讨论】:

  • 此代码无法正常工作——您的gemspec 不包括files 列表中的extconf.rb,因此在尝试安装时会出现错误。如果您的 gemspec 实际上包含 extconf.rb 但不包含任何 c 文件,那么您将看到您描述的行为,因此请确保它们也包含在内。
  • 我尝试在 FileList 中添加 ext/*/*.c 和 ext/*/*.h 并且它有效。这是正确的方法吗?你应该给出一个答案,以便我验证它。
  • 您的实际gemspec 是否包含extconf.rb(也许您使用*/*.rb 而不是lib/*.rb)?
  • 不,但正如我在guides.rubygems.org/gems-with-extensions 中看到的那样,我从一开始就有 s.extensions = %w(ext/myext/extconf.rb)
  • 这可以解释,我在测试中使用了不同的名称,但是在没有更改 myext 的情况下复制了您的 gemspec,所以我得到了错误。

标签: ruby gem ruby-c-extension


【解决方案1】:

你没有在你的filesgemspec 部分中包含源文件,所以在安装 gem 时没有什么要编译的。确保包含所有需要的文件:

s.files = FileList['lib/**/*.rb', 'ext/**/*.{rb,c,h}']

您不需要包含.so 文件,因为它们将在安装期间构建(实际上可能不是.so)。另外我认为你不需要添加to_aFileList 基本上已经是一个数组了)。

【讨论】:

  • 再多一点信息,编译后如何将.so文件放到lib/myext/目录下? (我使用加载so文件的myext.rb)?
  • @cedlemo gem 安装过程应该将其复制到lib 目录中,因此您无需执行任何操作 - 只需 require 'the_extension'(或您命名的任何名称)。跨度>
  • 如果您在 extconf.rb 中设置了 create_makefile(myext) 而不是 create_makefile(myext/myext),则不会。对此我很抱歉。谢谢你的帮助。
猜你喜欢
  • 2014-09-18
  • 2018-07-17
  • 1970-01-01
  • 1970-01-01
  • 2014-03-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多