2012-11-23 14 views
6

Voglio fare un gioiello, e quando qualcun altro cerca di usarlo con la risonanza magnetica utilizzerà il codice C, e quando lo useranno da JRuby userà il codice Java.Come faccio a creare una gemma destinata sia alla risonanza magnetica che a JRuby?

Le gemme nokogiri e puma lo fanno, e ho dato un'occhiata al loro codice, ma non ho visto come stavano accadendo.

+0

Vedere anche http://stackoverflow.com/questions/3642085/make-bundler-use-different-gems-for-different-platforms – knut

+0

Questo non è ciò di cui sto parlando. Voglio fare un gioiello e quando qualcun altro cerca di usarlo con la risonanza magnetica utilizzerà il codice C, e quando lo useranno da JRuby userà il codice Java. Le gemme nokogiri e puma lo fanno, e ho dato un'occhiata al loro codice, ma non ho visto come stavano accadendo – jshen

+0

Il modo più semplice sarebbe di scrivere la gemma in ruby, in questo modo la si esegue su 'jRuby' , 'MRI' o qualsiasi implementazione. Funzionerà bene. Non hai specificato quali sono le dipendenze esterne per il tuo gioiello. – nikhil

risposta

6

Ciò avviene mediante la compilazione incrociata della gemma per le diverse piattaforme a cui è destinato, utilizzando rvm (o altri strumenti simili per passare da un rubino all'altro) e rake-compiler.

Il file gemspec deve specificare i file necessari per ciascuna piattaforma; questo è fatto controllando la piattaforma la gemma viene compilato con:

Gem::Specification.new do |gem| 
# . . . 

    if RUBY_PLATFORM =~ /java/ 
    # package jars 
    gem.files += ['lib/*.jar'] 
    # . . . 
    else 
    # package C stuff 
    gem.files += Dir['ext/**/*.c'] 
    # . . . 
    gem.extensions = Dir['ext/**/extconf.rb'] 
    end 
end 

Nel Rakefile, dopo l'installazione rake-compiler, il modello è di solito la seguente:

spec = Gem::Specification.load('hello_world.gemspec') 

if RUBY_PLATFORM =~ /java/ 
    require 'rake/javaextensiontask' 
    Rake::JavaExtensionTask.new('hello_world', spec) 
else 
    require 'rake/extensiontask' 
    Rake::ExtensionTask.new('hello_world', spec) 
end 

Ma potrebbe essere necessario fare specifico compiti per le diverse piattaforme.

Con la risonanza magnetica, si compila con rake native gem; con JRuby, rake java gem - questo è dove uno strumento come rvm diventa utile. Finirai infine con diversi file gem per il tuo gioiello, uno per piattaforma, che potrai quindi rilasciare come gemma.

Vedere rake-compiler documentation per maggiori dettagli, o di controllare altri progetti che fanno lo stesso, come ad esempio redcloth o pg_array_parser (trovo che sono esempi migliori di nokogiri per questo).