いちばんやさしいCでつくるgem
C言語でシンプルなgemを作ってみましょう。
まずはフォルダーを用意します。
my_c_gemが今回のgemの名前です。
my_c_gem/ └── ext └── my_c_gem ├── extconf.rb └── my_c_gem.c
こんな感じです。 extconf.rbにはMakefileを自動生成するためのコードを書きます。
extconf.rb
require "mkmf" create_makefile "my_c_gem/my_c_gem"
my_c_gem.cには最初にrubyから呼ばれる初期化関数を書きます。まずは何もせずに MyCGemクラスを作るだけのコードをいれておきましょう。
my_c_gem.c
#include <ruby.h> void Init_my_c_gem(void) { rb_define_class("MyCGem",rb_cObject); }
ではまずMakefileを生成してみましょう。
cd ext/my_c_gem ruby extconf.rb
Makefileができるのでコンパイルしてみましょう。makeを実行します。
すると my_c_gem.bundleというファイルが出来上がります。このファイルがルビーに組み込まれるライブラリーファイルです。
my_c_gem/ └── ext └── my_c_gem ├── Makefile ├── extconf.rb ├── my_c_gem.bundle ├── my_c_gem.c └── my_c_gem.o
ではこのbundleファイルを組み込んでrubyを実行してみましょう。
bundleファイルのあるフォルダーで
ruby -Ilib:. -r my_c_gem -e "p MyCGem.new”
と実行します。
#<mycgem:0x007f9d7b87b138>
こんな感じに出力されます。
ではここまでをRakefileにして自動化してしまいましょう。
require "rake/extensiontask" Rake::ExtensionTask.new "my_c_gem" do |ext| ext.lib_dir = "lib/my_c_gem" end
これでrake compileでlibフォルダーが出来その中にbundleファイルがコンパイルされるようになります。
my_c_gem/ ├── Rakefile └── ext └── my_c_gem ├── Makefile ├── extconf.rb └── my_c_gem.c
一度make cleanしてから rake compileをしてみましょう。
my_c_gem/ ├── Rakefile ├── ext │ └── my_c_gem │ ├── Makefile │ ├── extconf.rb │ └── my_c_gem.c ├── lib │ └── my_c_gem │ └── my_c_gem.bundle └── tmp └── universal.x86_64-darwin15 ├── my_c_gem │ └── 2.0.0 │ ├── Makefile │ ├── my_c_gem.bundle │ └── my_c_gem.o └── stage └── lib └── my_c_gem └── my_c_gem.bundle
こんな感じでコンパイルが実行されます。
それではこれをbundle installできるようにしてみましょう。 まずはmy_c_gem.gemspecファイルをフォルダーのルートにつくります。
Gem::Specification.new do |spec| spec.name = "my_c_gem" spec.version = '1.0.0' spec.authors = ["yamshing"] spec.email = ["yamshing@..."] spec.summary = %q{My first C gem} spec.description = %q{This does nothing} spec.homepage = "" spec.license = "MIT" spec.files = [] spec.files = %w[ ext/my_c_gem/extconf.rb ext/my_c_gem/my_c_gem.c ] spec.require_paths = ["lib"] spec.extensions = %w[ext/my_c_gem/extconf.rb] spec.add_development_dependency "bundler", "~> 1.10" spec.add_development_dependency "rake", "~> 10.0" spec.add_development_dependency "minitest" end
ここで大切なのはspec.filesに必要なファイルをリストするのとspec.extensionsにextconf.rbを入れるところです。
さらにRakefileの中にrequire "bundler/gem_tasks”をたしてrake buildコマンドが使えるようにしましょう。
Rakefile
require "bundler/gem_tasks" require "rake/extensiontask" Rake::ExtensionTask.new "my_c_gem" do |ext| ext.lib_dir = "lib/my_c_gem" end
いよいよ実行です。 rake build してみましょう。
問題がなければpkgフォルダーができその中にmy_c_gem-1.0.0.gemができているはずです。
これをインストールしてみましょう。
gem install -l pkg/my_c_gem-1.0.0.gem -V
コンパイルがはじまり1 gem installedがでれば成功です。
実行してみましょう。ただrequire してp するだけです。
ruby -e "require 'my_c_gem/my_c_gem'; p MyCGem.new"
#<MyCGem:0x007f9de99c8720>のような出力がでれば成功です。
なにもしないgemが完成しました。