正在使用自定义扩展将 Ruby 应用程序部署到 Elastic Beanstalk,无法加载已编译的文件

Deploying Ruby app to Elastic Beanstalk with custom extension, unable to load compiled file

我一直在为我的一个项目开发 Ruby 扩展,我已经准备好将其部署到弹性 beanstalk。我决定做一个 gem,不是因为它真的对其他人有用,而主要是因为我以前从未做过。无论如何,我在 extconfig.rb 文件中使用 mkmf 来编译扩展:

# Loads mkmf which is used to make makefiles for Ruby extensions
require 'mkmf'

# Give it a name
extension_name = 'jeopardy'

create_makefile(extension_name)

然后,我的 gem规格:

Gem::Specification.new "jeopardy", "0.0.5" do |s|
  s.name        = 'jeopardy'
  s.version     = '0.0.5'
  s.date        = '2015-04-26'
  s.summary     = "Jeopardy Game Simulator"
  s.description = "A fast Monte Carlo simulation of the television game show Jeopardy!"
  s.authors     = ["Devin Shelly"]
  s.email       = 'devin@devinshelly.com'
  s.homepage    =
    'http://rubygems.org/gems/jeopardy'
  s.license       = 'MIT'
  s.extensions = %w[ext/jeopardy/extconf.rb]
  s.files = ["lib/jeopardy.rb", "lib/jeopardy/jeopardy.bundle"]
end

最后,我的 rakefile:

require "rake/extensiontask"

Rake::ExtensionTask.new "jeopardy" do |ext|
  ext.lib_dir = "lib/jeopardy"
end

require 'rake/testtask'

Rake::TestTask.new do |t|
  t.libs << 'test'
end

desc "Run tests"
task :default => :test

所以无论如何,我在那里设置了一切,我 运行 rake 编译,gem 构建,gem 安装,一切都很好。我把它推到 rubygem 在这里 (https://rubygems.org/gems/jeopardy),然后在我的 rails Gemfile 中,放入 gem 'jeopardy'。一切都很好,一切正常。但是,当我尝试使用 elastic beanstalk 部署我的应用程序时,出现以下错误:

LoadError: cannot load such file -- jeopardy/jeopardy.bundle
    from /opt/rubies/ruby-2.1.4/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:135:in `require'
    from /opt/rubies/ruby-2.1.4/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:135:in `rescue in require'
    from /opt/rubies/ruby-2.1.4/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:144:in `require'
    from /home/ec2-user/.gem/ruby/2.1.4/gems/jeopardy-0.0.5/lib/jeopardy.rb:238:in `<top (required)>'
    from /opt/rubies/ruby-2.1.4/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:135:in `require'
    from /opt/rubies/ruby-2.1.4/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:135:in `rescue in require'
    from /opt/rubies/ruby-2.1.4/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:144:in `require'
    from (irb):1
    from /opt/rubies/ruby-2.1.4/bin/irb:11:in `<main>'

指向我的 lib/jeopardy.rb 文件的最后一行,就是

require "jeopardy/jeopardy.bundle"

所以,这就是在我定义了我的 C 扩展使用的所有 类 和方法之后加载我的扩展的行。如果我通过 ssh 进入我的弹性 beanstalk 实例并检查 gem 目录,该文件确实存在,只是由于某种原因不会加载它。我在我的开发机器上 运行ning OSX 并且在我的 EB 实例上 Linux,fwiw。有谁知道为什么在我的机器上工作时要求文件在那里失败?

编辑:刚刚做了一些尝试,如果我从我的 EB 实例上安装的版本中删除该行,它就会加载。如果我创建一个 .rb 文件并从主 jeopardy.rb 文件中获取它,它就会加载。如果我 require_relative .bundle 文件,它仍然不会加载。所以,找到文件不是问题,它只是出于某种原因不喜欢 .bundle 文件。

好的,明白了。因此,我的代码编译为 .bundle 文件,但这是一个 OSX 特定文件。我实际需要做的是在 gem 规范中包含我所有的 .h 和 .c 文件,然后构建 gem。然后,在安装 gem 时,将构建这些文件(在 Linux 的情况下是一个 .so 文件)。我还需要将以下行添加到 extconfig.rb

$CFLAGS += " -std=c99"

否则,当我尝试在 Linux 上安装 gem 时,我遇到了错误。