5

我正在编写一个包含 C 扩展的 gem。通常,当我编写 gem 时,我会遵循 TDD 的过程,在那里我将编写一个失败的规范,然后处理代码直到它通过,等等......

在“ext/mygem/mygem.c”中使用我的 C 扩展名和在 gemspec 的“扩展名”中配置的有效 extconf.rb,我如何运行我的规范并仍然加载我的 C 扩展名?当我对 C 代码进行更改时,我需要采取哪些步骤来重新编译代码?

这可能是一个愚蠢的问题,但是从我的 gem 的开发源代码树中输入“bundle install”并不会构建任何本机扩展。当我手动运行时,ruby ext/mygem/extconf.rb我确实得到了一个 Makefile(在整个项目的根目录中),然后当我运行时make,我确实得到了一个共享对象(同样,在整个项目的根目录中)。我必须遵循错误的工作流程,因为我知道 .so 应该放在 lib/ 下。除非我应该在开发过程中手动完成?

4

2 回答 2

4

不知道这是否是“正确”的方式,但我过去这样做的方式是

添加

$: << File.dirname(__FILE__) + '/../ext'

致我的规范助手

然后有一个看起来像的 rakefile

require '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说明了这一点。

于 2012-03-30T14:24:36.887 回答
4

我最终采用的解决方案是在 github 上使用 rake-compiler:

https://github.com/luislavena/rake-compiler

您只需添加一个 rake 任务来进行编译(记录在自述文件中),然后使“规范”任务依赖于该构建阶段。

于 2012-05-05T04:42:06.057 回答