2

ruby ネイティブ エクステンションを作成しようとしていますが、rakewhich usesを実行ext/example_project/extconf.rbしてプロジェクトをビルドし、 でテストを実行するとtest/、テストの実行時に次のエラーが発生します。

./home/jbuesking/.rbenv/versions/2.3.0/bin/ruby: symbol lookup error: 
/home/jbuesking/repositories/example_project/lib/example_project/example_project.so: undefined symbol: some_function

私のファイルが正しくリンクされておらず、何らかの方法でextconf.rband/orを変更する必要があるRakefileことは確かですが、その方法がわかりません。

GitHubで問題を示す簡単なリポジトリを作成しました。rakeクローンを作成してプロジェクトのルートから実行すると、同じエラーで失敗します。

いくつかの追加情報:

  • ruby gemhoeを使用してプロジェクトを作成しましたsow example_project
  • 失敗した関数は、サブディレクトリ で定義された関数を呼び出そうとしていますext/example_project/c_example_project。私の実際のプロジェクトでは、ディレクトリの git サブモジュールを使用しますext/example_project。これにより、サブモジュールがサブディレクトリとして設定されます。サブモジュールは、フラット化された構造 (ルート ディレクトリ内のすべてのファイル) を持つ ac プロジェクトです。: この言い回しはわかりにくいかもしれませんが、重要な点は、ext/example_project/c_example_project呼び出しようとしているメソッドを持つ、ネストされた c プロジェクトが定義されていることです。

明確化が必要な場合はお知らせください。提供できるよう最善を尽くします。

4

3 に答える 3

4

それで、あなたがここに持っているいくつかの興味深い問題があります。デフォルトでは、mkmf は実際には、ソースを構築するための複数のディレクトリの指定をサポートしていません。

ここに見られるように、回避策があります(オブジェクトの設定に関するTakehiro Kuboのコメント):

https://www.ruby-forum.com/topic/4224640

基本的に、ファイル内の$objsグローバルを自分で構築します。extconf.rb

github コードを使用して、extconf.rb に追加したものを以下に示します。

extconf.rb

globs = [".", "c_example_project"].map do |directory|
  File.join(File.dirname(__FILE__), directory)
end.join(",")

$objs = Dir.glob("{#{globs}}/*.c").map do |file|
  File.join(File.dirname(file), "#{File.basename(file, ".c")}.o")
end

私が実際に各 c ソースへの絶対パスを作成していることに注意してください{.,c_example_project}/*.c。おそらく別のディレクトリから extconf.rb ファイルを実行しているため、.

さらに、tests/c 拡張機能にはいくつかのエラーがあります。で次の変更を行うとexample_project.c、テストの失敗が修正されます。

 static VALUE example_project_c_code_function()
 {
-    return some_function();
+    VALUE _string = rb_str_new2(some_function());
+    int _enc = rb_enc_find_index("UTF-8");
+    rb_enc_associate_index(_string, _enc);
+    return _string;
 }

説明

基本的に、extconf.rb の c_example_project.h ヘッダーをチェックしていても、some_function定義されているオブジェクト ファイルを実際に生成しているわけではありません。そのため、Ruby がロードする最終的な動的ライブラリをリンクすると、定義がなくsome_function、エラーが発生します。

于 2016-11-08T17:08:26.800 に答える
0

ネイティブ拡張機能を構築した経験はありませんが、mkmfソース コードからは、指定できるソース ディレクトリは 1 つだけのようです。両方のファイルをc_example_project親ディレクトリに移動したところ、すべてが適切にリンクされました。そうすればいいと思います。すべての一般的な gem (pg、nokogiri など) はこのようなコード構造を持ち、すべての *.c および *.h ファイルは 1 つのディレクトリにあります。

いつでもMakefile自分自身を作成できますが、それを維持するにはあまりにも多くの作業が必要になります。

PS。some_functionプロジェクトは正常にコンパイルされましたが、文字列へのポインターではなく適切なルビ文字列オブジェクトを返す必要があるため、セグメンテーション違反があります。

于 2016-11-03T07:57:17.353 に答える