我正在写一个包含C扩展的gem。通常当我写一个gem时,我会遵循TDD的过程,在那里我会编写一个失败的规范,然后处理代码直到它通过等等......
我的C扩展名在“ext / mygem / mygem.c”中,并且在gemspec的“扩展”中配置了有效的extconf.rb,如何运行我的规范并仍然加载了我的C扩展?当我更改C代码时,我需要采取哪些步骤来重新编译代码?
这可能是一个愚蠢的问题,但是从我的gem的开发源代码树里面输入'bundle install'并没有构建任何原生扩展。当我手动运行ruby ext/mygem/extconf.rb
时,我得到一个Makefile(在整个项目的根目录中),当我运行make
时,我确实得到了一个共享对象(同样,在整个项目的根目录中) )。我必须遵循错误的工作流程,因为我知道.so应该放在lib /下。除非我只是想在开发过程中手工做到这一点?
答案 0 :(得分:4)
不知道这是否是'正确'的方式,但我过去这样做的方式是
添加
$: << File.dirname(__FILE__) + '/../ext'
到我的规范助手
然后有一个看起来像
的rakefilerequire 'rspec/core/rake_task'
RSpec::Core::RakeTask.new('spec')
task :build do
Dir.chdir('ext') do
output = `ruby extconf.rb`
raise output unless $? == 0
output = `make`
raise output unless $? == 0
end
end
task :spec => :build
所以rake spec
每次为我构建c代码,内置库存在于ext /中。对加载路径的更改可确保加载此副本。这个github repo说明了这一点。
答案 1 :(得分:4)
我最终使用的解决方案是在github上使用rake-compiler:
https://github.com/luislavena/rake-compiler
您只需添加一个rake任务来进行编译(在README中记录),然后使'spec'任务依赖于该构建阶段。