正在使用自定义扩展将 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 时,我遇到了错误。
我一直在为我的一个项目开发 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 时,我遇到了错误。