2015-04-23 67 views
1

我有一个我想通过gem共享的项目。该扩展必须在用户系统上编译。因此编译必须在安装gem时完成。Ruby C扩展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 build myext.gemspec 

当我安装了宝石,我没有带任何错误消息:

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/例如。

+0

此代码不会如图所示工作 - 您的'gemspec'不包含'files'列表中的'extconf.rb',因此尝试安装时会出现错误。如果你的'gemspec'实际上包含'extconf.rb'而不是'c'文件,那么你会看到你描述的行为,所以确保它们也包含在内。 – matt

+0

我试图在FileList中添加ext/*/*。c和ext/*/*。h并且它可以工作。这是正确的做法吗?你应该回答,以便我可以验证它。 – cedlemo

+0

你的实际'gemspec'包含'extconf.rb'(也许你使用了'*/*。rb'而不是'lib/* .rb')? – matt

回答

2

您还没有在gemspecfiles部分中包含源文件,所以在安装gem时没有任何东西需要编译。请务必包括所有需要的文件:

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

你并不需要包括.so文件,因为它们会在安装过程中建立(和实际可能不被.so)。另外我不认为你需要添加to_a(一个FileList基本上是一个数组已经)。

+0

只需要更多的信息,编译后如何将.so文件放入lib/myext /目录中? (我使用加载这个文件的myext.rb)? – cedlemo

+0

@cedlemo宝石安装过程应该将它复制到'lib'目录中,所以你不应该做任何事情 - 只需要'需要'the_extension''(或者你命名的任何东西)。 – matt

+0

不,如果你在extconf.rb中设置了create_makefile(myext)而不是create_makefile(myext/myext)。对此我很抱歉。感谢您的帮助。 – cedlemo