>我在ext/Q/flagvalue.c中有一个简单的扩展名
我的 ext/Q/extconfig.rb 看起来像这样:
require 'mkmf'
create_makefile('Q/flagvalue')
Rakefile 中的任务设置如下:
Rake::ExtensionTask.new("Q") do |extension|
extension.lib_dir = 'lib/Q'
end
当我rake build
时,我得到以下输出:
mkdir -p tmp/x86_64-linux/Q/1.9.3cd tmp/x86_64-linux/Q/1.9.3/usr/local/rvm/rubies/ruby-1.9.3-p286/bin/ruby -I. ../../../../ext/Q/extconf.rb创建生成文件光盘 -cd tmp/x86_64-linux/Q/1.9.3做编译。。/../../../ext/Q/flagvalue.c链接共享对象 Q/flagvalue.so光盘 -install -c tmp/x86_64-linux/Q/1.9.3/Q.so lib/Q/Q.so耙子中止了!没有这样的文件或目录 - tmp/x86_64-linux/Q/1.9.3/Q.so
因此,编译器似乎编译并链接 flagvalue.so,安装程序尝试安装不存在的 Q.so......此错误从何而来,我该怎么办?
在你的Rakefile
试试这个:
Rake::ExtensionTask.new 'flagvalue' do |extension|
extension.ext_dir = 'ext/Q'
extension.lib_dir = 'lib/Q'
end
这确实需要一些重复,因为 Rake 任务不知道您在extconf
中指定的目标(即它不知道Q
目录),因此您必须再次指定。这也意味着任务在项目中tmp
目录下创建的结构中不会有Q
目录,但这可能不是问题。
好的,经过一些挖掘(和一些模糊的猜测:-Δ),我找到了解决方案:
我刚刚为我的 gemspec (来自 Writehack.com)获得了一些代码,如下所示:
s.executables = `git ls-files -- bin/*`.split("n").map{ |f| File.basename(f) }
此方法的问题在于,您必须在存储库中已经具有刚编译的二进制文件。 正确的方法是从ext-directory获取*.c文件并将它们重命名为*.so,如下所示:
s.executables = s.files.grep(%r{^ext/.*c$}).map{ |f| File.basename(f, '.c') + '.so'}
s.bindir = 'bin'
并且还向Rakefile
的扩展任务添加一个bindir,并使其从规范中获取文件:
spec = Gem::Specification.load('Q.gemspec')
spec.executables.each do |f|
Rake::ExtensionTask.new('Q', spec) do |ext|
ext.name = f.gsub(/.so$/,'')
ext.tmp_dir = 'tmp'
ext.lib_dir = 'bin'
end
end
:-Δ