Pregunta

I have a simple extension in ext/Q/flagvalue.c

My ext/Q/extconfig.rb looks like this:

require 'mkmf'
create_makefile('Q/flagvalue')

The task in Rakefile is set-up just so:

Rake::ExtensionTask.new("Q") do |extension|
  extension.lib_dir = 'lib/Q'
end

when I rake build, i get the following output:

mkdir -p tmp/x86_64-linux/Q/1.9.3
cd tmp/x86_64-linux/Q/1.9.3
/usr/local/rvm/rubies/ruby-1.9.3-p286/bin/ruby -I. ../../../../ext/Q/extconf.rb
creating Makefile
cd -
cd tmp/x86_64-linux/Q/1.9.3
make
compiling ../../../../ext/Q/flagvalue.c
linking shared-object Q/flagvalue.so
cd -
install -c tmp/x86_64-linux/Q/1.9.3/Q.so lib/Q/Q.so
rake aborted!
No such file or directory - tmp/x86_64-linux/Q/1.9.3/Q.so

So it seems like the compiler compiles and links flagvalue.so and the installer tries to install non-existent Q.so… where does this error come from and what can I do about it?

¿Fue útil?

Solución 2

Ok, after some digging (and some vague guessing :-Δ) I found the solution:

I just got some code for my gemspec (from Writehack.com), that was so:

s.executables   = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }

the problem with this method is that you'd have to have the just-to compile-binaries already in your repository. the correct way was to get the *.c-files from ext-directory and rename them to *.so like this:

s.executables   = s.files.grep(%r{^ext/.*c$}).map{ |f| File.basename(f, '.c') + '.so'}
s.bindir        = 'bin'

and also adding a bindir to Rakefile's ExtensionTask and make it get its files from spec:

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

:-Δ

Otros consejos

Try this in your Rakefile:

Rake::ExtensionTask.new 'flagvalue' do |extension|
  extension.ext_dir = 'ext/Q'
  extension.lib_dir = 'lib/Q'
end

This does entail some duplication, as the Rake tasks doesn’t know what you specify as your target in extconf (i.e. it doesn’t know about the Q directory), so you have to specify again. This also means there won’t be a Q directory in the structure the the task creates under the tmp dir in your project, but that’s probably not a problem.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top