KyotoCabinetのRubyバインディングがFreeBSDで使えなくなった
% wget http://fallabs.com/kyotocabinet/rubypkg/kyotocabinet-ruby-1.32.tar.gz % tar xf kyotocabinet-ruby-1.32.tar.gz % cd kyotocabinet-ruby-1.32 % ruby extconf.rb extconf.rb:18:in `<main>': Use RbConfig instead of obsolete and deprecated Config. extconf.rb:18:in `<main>': Use RbConfig instead of obsolete and deprecated Config. setting variables ... $CFLAGS = -I. -I/usr/local/include -Wall -O2 -pipe -fno-strict-aliasing -fPIC -O2 $LDFLAGS = -L. -Wl,-rpath,/usr/lib:/usr/local/lib -fstack-protector -rdynamic -L. -L/usr/local/lib $libs = -lkyotocabinet -lz -lrt -lpthread -lm -lc checking for kccommon.h... no *** extconf.rb failed *** Could not create Makefile due to some reason, probably lack of necessary libraries and/or headers. Check the mkmf.log file for more details. You may need configuration options.
kcommon.hが無いのか.
% locate kccommon.h /usr/local/include/kccommon.h /usr/ports/databases/kyotocabinet/files/patch-kccommon.h
いや,あるだろ.
ログを見てみる.
% cat mkmf.log have_header: checking for kccommon.h... -------------------- no "cc -o conftest -I/usr/local/include/ruby-2.1//amd64-freebsd10 -I/usr/local/include/ruby-2.1//ruby/backward -I/usr/local/include/ruby-2.1/ -I. -I/usr/local/include -I. -I/usr/local/include -Wall -O2 -pipe -fno-strict-aliasing -fPIC -O2 conftest.c -L. -L/usr/local/lib -L. -Wl,-rpath,/usr/lib:/usr/local/lib -fstack-protector -rdynamic -L. -L/usr/local/lib -lkyotocabinet -lz -lrt -lpthread -lm -lc -lruby21 -lexecinfo -lcrypt -lm -L/usr/local/lib -pthread -lc" checked program was: /* begin */ 1: #include "ruby.h" 2: 3: int main(int argc, char **argv) 4: { 5: return 0; 6: } /* end */ "g++ -E -I/usr/local/include/ruby-2.1//amd64-freebsd10 -I/usr/local/include/ruby-2.1//ruby/backward -I/usr/local/include/ruby-2.1/ -I. -I/usr/local/include -I. -I/usr/local/include -Wall -O2 -pipe -fno-strict-aliasing -fPIC -O2 conftest.c -o conftest.i" checked program was: /* begin */ 1: #include "ruby.h" 2: 3: #include <kccommon.h> /* end */
問題が無いように見える.ダミーのファイルを作ってみる.
% echo '#include <kccommon.h>' > conftest.c % g++ conftest.c g++: コマンドが見つかりません.
ん?!
% ls -l /usr/{bin,local/bin}/g++* -r-xr-xr-x 4 root wheel 550816 3月 14 10:58 /usr/local/bin/g++47
オーマイガッ.
ハードリンクにする.
# ln -v /usr/local/bin/g++47 /usr/local/bin/g++ /usr/local/bin/g++ => /usr/local/bin/g++47
再チャレンジ.
% ruby extconf.rb extconf.rb:18:in `<main>': Use RbConfig instead of obsolete and deprecated Config. extconf.rb:18:in `<main>': Use RbConfig instead of obsolete and deprecated Config. setting variables ... $CFLAGS = -I. -I/usr/local/include -Wall -O2 -pipe -fno-strict-aliasing -fPIC -O2 $LDFLAGS = -L. -Wl,-rpath,/usr/lib:/usr/local/lib -fstack-protector -rdynamic -L. -L/usr/local/lib $libs = -lkyotocabinet -lz -lrt -lpthread -lm -lc checking for kccommon.h... yes creating Makefile
警告は無視.
% make compiling kyotocabinet.cc kyotocabinet.cc:602:5: warning: 'rb_thread_blocking_region' is deprecated [-Wdeprecated-declarations] rb_thread_blocking_region(execute_impl, func, RUBY_UBF_IO, NULL); ^ /usr/local/include/ruby-2.1/ruby/intern.h:870:18: note: 'rb_thread_blocking_region' declared here DEPRECATED(VALUE rb_thread_blocking_region(rb_blocking_function_t *func, void *data1, ^ /usr/local/include/ruby-2.1//amd64-freebsd10/ruby/config.h:115:52: note: expanded from macro 'DEPRECATED' #define DEPRECATED(x) __attribute__ ((deprecated)) x ^ kyotocabinet.cc:2185:20: error: no member named 'ruby_close' in 'kyotocabinet::PolyDB' rv_ = db_->close(); ~~~ ^ /usr/local/include/ruby-2.1/ruby/subst.h:17:15: note: expanded from macro 'close' #define close ruby_close ^ kyotocabinet.cc:2195:14: error: no member named 'ruby_close' in 'kyotocabinet::PolyDB' rv = db->close(); ~~ ^ /usr/local/include/ruby-2.1/ruby/subst.h:17:15: note: expanded from macro 'close' #define close ruby_close ^ 1 warning and 2 errors generated. *** Error code 1
ショボン.
こいつだけ倒せばなんとかなるような気がする.
kyotocabinet.cc:2185:20: error: no member named 'ruby_close' in 'kyotocabinet::PolyDB'
エラーはここ.
rv_ = db_->close();
db_はこう定義されてる感じ.
kc::PolyDB* db;
PolyDBは/usr/local/include/kcpolydb.hで定義されているクラスなので,close()はそのインスタンスのメッソッドが呼ばれている.
ところでエラーで出ている,ruby_closeというのは,KyotoCabinetのインクルードファイルの中には確かに出てこない.
% grep ruby_close /usr/local/include/* %
ruby_closeでググると,似たようなことで悩んでいるっぽい人がいた.
なぜか数学者にはワイン好きが多い
自分だ...
/usr/local/include/ruby-2.1/ruby/ruby.hが原因らしい.
そう言われてみると,コンパイル時のエラーメッセージで出ていたね.note,って.
/usr/local/include/ruby-2.1/ruby/subst.h:17:15: note: expanded from macro 'close' #define close ruby_close
ちょっと追ってみれば分かることで,
バカにされた気がするが気にせず,指摘のとおりに直して再チャレンジ.
% ruby extconf.rb extconf.rb:18:in `<main>': Use RbConfig instead of obsolete and deprecated Config. extconf.rb:18:in `<main>': Use RbConfig instead of obsolete and deprecated Config. setting variables ... $CFLAGS = -I. -I/usr/local/include -Wall -O2 -pipe -fno-strict-aliasing -fPIC -O2 -DRUBY_DONT_SUBST $LDFLAGS = -L. -Wl,-rpath,/usr/lib:/usr/local/lib -fstack-protector -rdynamic -L. -L/usr/local/lib $libs = -lkyotocabinet -lz -lrt -lpthread -lm -lc checking for kccommon.h... yes creating Makefile % make compiling kyotocabinet.cc kyotocabinet.cc:602:5: warning: 'rb_thread_blocking_region' is deprecated [-Wdeprecated-declarations] rb_thread_blocking_region(execute_impl, func, RUBY_UBF_IO, NULL); ^ /usr/local/include/ruby-2.1/ruby/intern.h:870:18: note: 'rb_thread_blocking_region' declared here DEPRECATED(VALUE rb_thread_blocking_region(rb_blocking_function_t *func, void *data1, ^ /usr/local/include/ruby-2.1//amd64-freebsd10/ruby/config.h:115:52: note: expanded from macro 'DEPRECATED' #define DEPRECATED(x) __attribute__ ((deprecated)) x ^ kyotocabinet.cc:2185:20: error: no member named 'ruby_close' in 'kyotocabinet::PolyDB' rv_ = db_->close(); ~~~ ^ /usr/local/include/ruby-2.1/ruby/subst.h:17:15: note: expanded from macro 'close' #define close ruby_close ^ kyotocabinet.cc:2195:14: error: no member named 'ruby_close' in 'kyotocabinet::PolyDB' rv = db->close(); ~~ ^ /usr/local/include/ruby-2.1/ruby/subst.h:17:15: note: expanded from macro 'close' #define close ruby_close ^ 1 warning and 2 errors generated. *** Error code 1
ダメだよ.変わらないよ.
Makefileの中を見ていて,
CFLAGS = $(CCDLFLAGS) -I. -I/usr/local/include -Wall -O2 -pipe -fno-strict-aliasing -fPIC -O2 -DRUBY_DONT_SUBST $(ARCH_FLAG) INCFLAGS = -I. -I$(arch_hdrdir) -I$(hdrdir)/ruby/backward -I$(hdrdir) -I$(srcdir) DEFS = CPPFLAGS = -DHAVE_KCCOMMON_H -I/usr/local/include $(DEFS) $(cppflags)
ひょっとしてkyotocabinet.ccは,さっきのg++が使われていて,CPPFLAGSにも手をいれないとダメな気がしてきたよ.
CPPFLAGS = -DHAVE_KCCOMMON_H -I/usr/local/include $(DEFS) $(cppflags) ↓ CPPFLAGS = -DHAVE_KCCOMMON_H -I/usr/local/include $(DEFS) $(cppflags) -DRUBY_DONT_SUBST
不屈の再チャレンジ.
% make compiling kyotocabinet.cc kyotocabinet.cc:602:5: warning: 'rb_thread_blocking_region' is deprecated [-Wdeprecated-declarations] rb_thread_blocking_region(execute_impl, func, RUBY_UBF_IO, NULL); ^ /usr/local/include/ruby-2.1/ruby/intern.h:870:18: note: 'rb_thread_blocking_region' declared here DEPRECATED(VALUE rb_thread_blocking_region(rb_blocking_function_t *func, void *data1, ^ /usr/local/include/ruby-2.1//amd64-freebsd10/ruby/config.h:115:52: note: expanded from macro 'DEPRECATED' #define DEPRECATED(x) __attribute__ ((deprecated)) x ^ 1 warning generated. linking shared-object kyotocabinet.so
イケたよ.
# make install /usr/bin/install -c -o root -g wheel -m 0755 kyotocabinet.so /usr/local/lib/ruby/site_ruby/2.1/amd64-freebsd10 installing default kyotocabinet libraries
テストをする.
% ruby -e 'require "kyotocabinet"; db = KyotoCabinet::DB::new; db.open("test.kch"); db["key1"] = "val1"; db.close()' % kcpolymgr list -pv test.kch key1 val1
いい感じ.