簡體   English   中英

Ruby 與 gmp 的加載錯誤

[英]Ruby LoadError with gmp

$ gem install gmp
Building native extensions. This could take a while...
Successfully installed gmp-0.7.43
Parsing documentation for gmp-0.7.43
Done installing documentation for gmp after 0 seconds
1 gem installed


$ cat gmp-test.rb
require 'gmp'

$ /opt/src/ruby-3.2.0/bin/ruby gmp-test.rb
<internal:/opt/src/ruby-3.2.0/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:85:in `require': cannot load such file -- /home/dunham/.local/share/gem/ruby/3.2.0/gems/gmp-0.7.43/lib/../ext/gmp (LoadError)
    from <internal:/opt/src/ruby-3.2.0/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:85:in `require'
    from /home/dunham/.local/share/gem/ruby/3.2.0/gems/gmp-0.7.43/lib/gmp.rb:9:in `<top (required)>'
    from <internal:/opt/src/ruby-3.2.0/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:159:in `require'
    from <internal:/opt/src/ruby-3.2.0/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:159:in `rescue in require'
    from <internal:/opt/src/ruby-3.2.0/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:149:in `require'
    from gmp-test.rb:1:in `<main>'
<internal:/opt/src/ruby-3.2.0/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:85:in `require': cannot load such file -- gmp (LoadError)
    from <internal:/opt/src/ruby-3.2.0/lib/ruby/site_ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:85:in `require'
    from gmp-test.rb:1:in `<main>'

圖書館似乎已經死了。 它期望gmp.so位於ext目錄中,但它最終位於lib目錄中,它可能是新的rubygems不同的方式做事。

>> require "gmp"
<internal:/home/alex/.rbenv/versions/3.2.0/lib/ruby/3.2.0/rubygems/core_ext/kernel_require.rb>:85:in 'require': 
cannot load such file -- /home/alex/.rbenv/versions/3.2.0/lib/ruby/gems/3.2.0/gems/gmp-0.7.43/lib/../ext/gmp (LoadError)
$ ls $(dirname $(gem which gmp))
gmp.rb  gmp.so
#  move ^ that to ../ext/

$ mv $(dirname $(gem which gmp))/gmp.so $(dirname $(gem which gmp))/../ext/
>> require "gmp"
=> true
>> GMP::Z(0)
=> 0

更新

從鏈接的日志來看,您似乎仍然沒有加載gmp.so ,這是定義所有類的地方。 您可以將gmp.so復制到您的應用中:

# copy `gmp.rb`
$ cp $(gem which gmp) .
# copy `gmp.so`
$ cp $(dirname $(gem which gmp))/gmp.so .
# or if you moved it to ext
$ cp $(dirname $(gem which gmp))/../ext/gmp.so .
$ touch app.rb
$ ls
app.rb  gmp.rb  gmp.so

gmp.rb定義了GMP.sprintf方法,如果這不是必需的方法並且您不使用它,則可以刪除該文件。

# gmp.rb

# require 'rbconfig'
#
# ENV['PATH'] = [File.expand_path(
#   File.join(File.dirname(__FILE__), "..", "ext")
# ), ENV['PATH']].compact.join(';') if RbConfig::CONFIG['host_os'] =~ /(mswin|mingw|mingw32)/i
#
# require File.dirname(__FILE__) + '/../ext/gmp'

# unless RUBY_VERSION =~ /^1.8/
  module GMP
    def self.sprintf(format, *args)
      first_pct = format.index '%'
      result = format[0...first_pct]
      #format.gsub(/(?<!%)%[0#+ ']*[0-9]*.?[0-9]*[a-zA-Z][^%]*/) do |fragment|
      format.gsub(Regexp.new('(?<!%)%[0#+ \']*[0-9]*.?[0-9]*[a-zA-Z][^%]*')) do |fragment|
        arg = args.shift
        if fragment =~ /%[0#+ ']*[0-9]*.?[0-9]*[ZQF]/
          result << sprintf2(fragment, arg)
        elsif fragment =~ /%[0#+ ']*[0-9]*.?[0-9]*[PR]/ && GMP.const_defined?(:MPFR_VERSION)
          result << GMP::F.sprintf2(fragment, arg)
        else
          result << (fragment % arg)
        end
      end
      result
    end
  end
# end
# app.rb

require_relative "gmp.so"
p GMP::Z
p GMP::Z(0)
p GMP::Q
p GMP::F

require_relative "gmp.rb"
p GMP.sprintf "%Zd", GMP.Z(0)
$ ruby --yjit -v
ruby 3.2.0 (2022-12-25 revision a528908271) +YJIT [x86_64-linux]
$ ruby --yjit app.rb
GMP::Z
0
GMP::Q
GMP::F
"0"

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM