【问题标题】:How to get Ruby to find a native lib?如何让 Ruby 找到原生库?
【发布时间】:2012-02-16 16:16:06
【问题描述】:

我在 /usr/local/lib 中安装了一些本地库。

我现在正在尝试安装一个需要这些的 gem,以便 正确构建,但是 gem 构建失败,因为它找不到 图书馆。

gem 的 extconf.rb 文件试图确认它可以找到库 have_library() 但由于某种原因失败了。

我尝试设置一堆环境变量,但似乎没有任何效果:

irb(main):003:0> require 'mkmf'
=> true
irb(main):004:0> have_library('gecodesearch')
checking for main() in -lgecodesearch... no
=> false
irb(main):005:0> ENV['LD_LIBRARY_PATH']='/usr/local/lib'
=> "/usr/local/lib"
irb(main):006:0> have_library('gecodesearch')
checking for main() in -lgecodesearch... no
=> false
irb(main):007:0> ENV['DYLD_LIBRARY_PATH']='/usr/local/lib'
=> "/usr/local/lib"
irb(main):008:0> have_library('gecodesearch')
checking for main() in -lgecodesearch... no
=> false
irb(main):009:0> have_library('libgecodesearch')
checking for main() in -llibgecodesearch... no
=> false
irb(main):010:0> ENV['C_INCLUDE_PATH']='/usr/local/lib'
=> "/usr/local/lib"
irb(main):011:0> have_library('gecodesearch')
checking for main() in -lgecodesearch... no
=> false
irb(main):012:0> ENV['PATH']='/usr/local/lib'
=> "/usr/local/lib"
irb(main):013:0> have_library('gecodesearch')
checking for main() in -lgecodesearch... no
=> false 

解决这个问题的最佳方法是什么?

【问题讨论】:

  • 我从来没有直接遇到过这种情况,但是我假设如果您将路径添加到$LOAD_PATH(也称为$:),一切都会起作用:$: << "/usr/local/lib/mylib" 或者,使用一个或多个 -I 选项调用 Ruby 解释器:ruby -I/usr/local/lib/mylib foo.rb
  • 不幸的是,不,不是这种情况irb(main):001:0> require 'mkmf'=> trueirb(main):002:0> $: << "/usr/local/lib"=> ["/usr/pkg/lib/ruby/site_ruby/1.9", "/usr/pkg/lib/ruby/site_ruby/1.9/i386-netbsdelf", "/usr/pkg/lib/ruby/site_ruby", "/usr/pkg/lib/ruby/vendor_ruby/1.9", "/usr/pkg/lib/ruby/vendor_ruby/1.9/i386-netbsdelf", "/usr/pkg/lib/ruby/vendor_ruby", "/usr/pkg/lib/ruby/1.9", "/usr/pkg/lib/ruby/1.9/i386-netbsdelf", "/usr/local/lib", "/usr/local/lib"]irb(main):003:0> have_library('gecodesearch')在-lgecodesearch中检查main()... no => false`跨度>
  • 不要将/usr/local/lib的根添加到加载路径,加载你需要的库的实际目录/目录。 Ruby 不会分层搜索加载路径中目录下的所有目录。
  • .so 文件直接在 /usr/local/lib 中,而不是某个子目录。默认情况下,该选择是由 lib 的 Makefile 做出的。
  • 试试nm /usr/local/lib/libgecodesearch.so,看看它是否包含_main或main符号

标签: ruby rubygems


【解决方案1】:

我已经阅读了 cmets 并且知道您成功了,但我认为我有解决问题的正确方法。

have_library 检查是否可以在您的环境中使用给定的库。它通过包含库头文件并在临时 C 源文件中使用其函数之一来实现这一点。如果成功,则该库必须可用。

have_library 'geocodesearch'
checking for main() in -lgecodesearch... no

have_library 无法使用来自geocodesearchmain 函数。这意味着该库不可用或该函数不存在。在你的情况下,可能是后者。

您可以通过传递第二个参数来告诉have_library 要尝试哪个函数。例如:

have_library 'geocodesearch', 'geocodesearch_version'
checking for geocodesearch_version() in -lgecodesearch...

如果您不指定,它只会查找main 函数。您还可以指定要包含的标题:

have_library 'geocodesearch', 'geocodesearch_version', %w(geocode/search.h)

在 cmets 中,您说您通过简单地消除 have_library 调用解决了您的问题。这是一个本地化的解决方案;您必须将其重新应用到任何新版本的 gem。

我建议向作者发送包含必要调整的拉取请求。该错误将被永久修复,您还将帮助可能遇到相同问题的其他人。

mkmf参考:

【讨论】:

    【解决方案2】:

    首先添加find_library 对我有用:

    find_library('library_name', 'library_function', '/usr/local/lib')
    have_library('library_name', 'library_function', 'library_header')
    

    我在尝试构建依赖于来自 TruffleRuby 21.3.0 下 /usr/local/lib 的自定义库的本机扩展 gem 时遇到了这个问题,而相同的 gem 在 CRuby 2.7.x 下工作得很好。

    基于mkmf MakeMakefile docs,似乎find_library 将接受搜索路径列表,have_library 将检查标题,但由于某种原因have_library 不接受搜索路径。但是,find_library 会将它找到的路径添加到内部搜索路径中,然后have_library 将能够找到该库。

    您可能只使用find_library 就可以逃脱惩罚,但我同时使用这两种方法,因为据我所知,have_library 也可以查找库头。


    以下是我从 graalvm-native-clang -o conftest 编译命令中看到的错误消息,以供将来的搜索者参考:

    conftest.c:14:57: error: use of undeclared identifier 'library_function'
    int t(void) { void ((*volatile p)()); p = (void ((*)()))library_function; return !p; }
    
    ld.lld: error: unable to find library -llibrary_name
    clang-12: error: linker command failed with exit code 1 (use -v to see invocation)
    

    【讨论】:

      猜你喜欢
      • 2020-03-16
      • 1970-01-01
      • 2020-05-09
      • 2011-01-12
      • 1970-01-01
      • 1970-01-01
      • 2017-02-22
      • 1970-01-01
      相关资源
      最近更新 更多