使用自定义扩展将 Ruby 应用程序部署到 Elastic Beanstalk,无法加载编译文件
Posted
技术标签:
【中文标题】使用自定义扩展将 Ruby 应用程序部署到 Elastic Beanstalk,无法加载编译文件【英文标题】:Deploying Ruby app to Elastic Beanstalk with custom extension, unable to load compiled file 【发布时间】:2015-07-06 14:07:13 【问题描述】:我一直在为我的一个项目开发一个 Ruby 扩展,并且我已经准备好将它部署到弹性 beanstalk。我决定制作一颗宝石,不是因为它对其他人真的有用,而主要是因为我以前从未制作过。无论如何,我在我的 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)
然后,我的 gemspec:
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 compile、gem build、gem install,一切都很好。我把它推到了这里的 rubygems (https://rubygems.org/gems/jeopardy),然后在我的 rails Gemfile 中,把 gem 'jeopardy' 扔进去。一切都很好,一切正常。但是,当我尝试使用弹性 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 目录,该文件确实存在,只是由于某种原因它不会加载它。我在我的开发机器上运行 OSX,在我的 EB 实例上运行 Linux,fwiw。有谁知道为什么要求该文件在我的机器上运行时会失败?
编辑:只是做了一些尝试,如果我从我的 EB 实例上的已安装版本中删除该行,它会加载。如果我创建一个 .rb 文件并从主 jeopardy.rb 文件中需要它,它会加载。如果我 require_relative .bundle 文件,它仍然不会加载。所以,找到文件不是问题,只是出于某种原因它不喜欢 .bundle 文件。
【问题讨论】:
【参考方案1】:好吧,想通了。因此,我的代码编译为 .bundle 文件,但这是 OSX 特定的文件。我真正需要做的是在 gemspec 中包含我所有的 .h 和 .c 文件,然后构建 gem。然后,在安装 gem 时,将构建这些文件(在 Linux 的情况下,是一个 .so 文件)。我还需要将以下行添加到 extconfig.rb
$CFLAGS += " -std=c99"
否则,当我尝试在 Linux 上安装 gem 时,会出现错误。
【讨论】:
以上是关于使用自定义扩展将 Ruby 应用程序部署到 Elastic Beanstalk,无法加载编译文件的主要内容,如果未能解决你的问题,请参考以下文章
ASP.NET Core Web 应用程序开发期间部署到IIS自定义主机域名并附加到进程调试
ruby 扩展RSpec :: Matchers :: BuiltIn :: Match的自定义匹配器也可以指定捕获组。
如何使用像filezilla这样的ftp服务器将没有vercel的下一个js应用程序部署到自定义服务器