ruby
  • gem
  • rake
  • rakefile
  • 2012-11-22 129 views 0 likes 
    0

    我在內線的簡單擴展/ Q/flagvalue.c如何編譯Ruby擴展

    我的分機/ Q/extconfig.rb看起來是這樣的:

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

    在Rake文件的任務設置 - 最多隻是如此:

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

    當我rake build,我得到下面的輸出:

    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 
    

    所以它看起來像編譯器編譯和鏈接flagvalue.so和安裝程序將嘗試安裝不存在Q.so ...哪裏是從哪裏來的這個錯誤,我能做些什麼呢?

    回答

    0

    好了,經過一番挖掘(和一些模糊的猜測:-Δ)我找到了解決辦法:

    我只是得到了一些代碼爲我gemspec(從Writehack.com),即是如此:

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

    這種方法的問題在於,你必須在你的倉庫中擁有剛剛編譯的二進制文件。正確的做法是得到EXT-目錄中的* .c-文件,並將它們以*重命名。所以像這樣的:

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

    並且還加入了BINDIR到Rakefile的ExtensionTask並使其從中獲取它的文件規格:

    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 
    

    :-Δ

    1

    Rakefile試試這個:

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

    這的確需要有一些重複,因爲Rake任務,不知道你作爲你的目標在extconf指定的內容(即不知道的Q目錄),所以你必須重新指定。這也意味着在您的項目中tmp目錄下任務創建的結構中不會有Q目錄,但這可能不是問題。

    相關問題