0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

RubyのC拡張でサブディレクトリに配置したCファイルを使いたい! ー symbol lookup error を回避する

Last updated at Posted at 2021-12-18

はじめに

RubyのC拡張でバインディングを作成する場合、ext/fooba にCファイルを配置する。伝統的なRubyのGemはこのディレクトリにフラットにCファイルを展開するようだ。けれども、サブディレクトリを使いたい場合がある。具体的には Git submoduleなどで、バインディング先のCのライブラリを ext/foobar に配置してバージョン管理したいような場合だ。

その場合、$INCFLAGS$VPATH を利用するという方法がよく紹介される。

INCFLAGS << " -I$(srcdir)/libFooBar"
VPATH    << " $(srcdir)/libFooBar"

しかしこの方法は一見するとrake compileが成功するのだが、いざテストを実行すると、と symbol lookup error が発生する。そして ldd をしても特に足りない共有ライブラリなどはない。どうすればいいのだろうか?

どうればいいのか? 一つの方法

インターネット上を探しても回答は多くない。

mysqlバインディングや、opencvバインディングのような有名なGemを参考にしようと見に行っても、1つのディレクトリで構成されている。

それでも英語のStackOverFlowにこの問題に対する回答があった。大域変数 $obj を指定すればいいそうだ。

たとえば、次のような方法である。

$objs = Dir.glob([".c", "libFooBar/*.c"], base: __dir__)
           .map { |f| File.expand_path(f, __dir__) }
           .map { |f| f.sub(/\.c$/, ".o") }

とする。ただし、この回答はkojix2がStackOverFlowの回答を参考に書いてみたらうまくいった方法にすぎない。(フィードバックのため3番目に投稿してある)、うまくいかない場合は書き直してほしい。何が問題で、どうすればよかったのかQiitaやブログの記事にしたり、コメントに書き込んで情報をRubyコミュニティにフィードバックしてググラビリティの改善に貢献してほしいです。

ちなみに、これを指定すると、#INCFLAGS$VPATH は特に必要ないようだ。
どうしてそうなるのか仕組みはわからない。

追記

ruby-jp のslackに質問をして、C拡張の作成にサブディレクトリの使用はとくに問題ない(非推奨ではない)との回答をいただきました。Rubyの拡張ライブラリは一つのディレクトリにフラットにファイル展開されていることが多いが、別にそのようにしたほうがいいという決まりはないそうです。

この記事は以上です。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?