问题
I have a Rails app that I'm developing on Windows and deploying to Linux. I suspect I'll just switch entirely over to Linux in the future. Anyway, on Linux I need 'execjs' and 'therubyracer' but I don't need those in Win7. So I put these lines in my gemfile:
gem 'therubyracer', :platforms => :ruby
gem 'execjs', :platforms => :ruby
Ran a bundle install
on the Linux VM and the app started up fine. But on Windows I get:
Uncaught exception: Could not find execjs-1.2.11 in any of the sources
Now, from what I read (here under PLATFORMS) it tells me that "If a gem should only be used in a particular platform or set of platforms, you can specify them" and the sample is this:
gem "weakling", :platforms => :jruby
And it says "ruby C Ruby (MRI) or Rubinius, but NOT Windows
". So to me that says that bundler should be ignoring the execjs
line on Windows. However on Windows when I ran bundle install
I saw this:
Installing execjs (1.2.11)
So that says to me I'm missing something about the docs or bundler is ignoring the platforms command. Am I doing something wrong?
PS>bundle -v
Bundler version 1.0.21
回答1:
:platforms => :ruby
does indeed exclude gems from being installed on Windows.
However, it does not work in a cygwin environment. In cygwin, it considers the platform to be :mri.
You'll also notice that ruby -e 'puts RUBY_PLATFORM'
outputs i386-cygwin
, not i386-mingw32
or i386-mswin
like it would on Windows ruby.
Were you working in a cygwin environment?
回答2:
Add code to the Gemfile like this that excludes/includes gems depending on the OS platform
if RUBY_PLATFORM=~ /win32/
gem "windows-only-gem"
else
gem "os-agnostic-gem"
end
回答3:
Bundler concept of platform differs from normal understanding of RUBY_PLATFORM
matching or RubyGems behaviors.
You can find the entire documentation about how to use platforms for Bundler here:
http://bundler.io/v1.14/man/gemfile.5.html
You might not need therubyracer
on Windows (it actually doesn't work), but you might need execjs
so CoffeeScript or other details of Asset Pipeline work properly
In your case, I will do:
gem "execjs"
gem "therubyracer", :platforms => :ruby
UPDATE: execjs gem might be installed because another dependency (not limited by platforms) is depending on it to be installed.
回答4:
Rails 5:
if Gem.win_platform?
# Install gem for Windows
else
# Install another gem
end
回答5:
I'm not sure about the :platform switch as I've never used it. However, an alternative that I think will work for your scenario would be to wrap your declarations for those two gems in a 'group' block in your Gemfile. Such as...
group :production do
gem 'therubyracer'
gem 'execjs'
end
This way, those gems will only be used in your production environment, not in development.
Note that I believe bundler will still install them in development (something to do with dependency checking), but they won't actually get loaded and therefore shouldn't cause problems.
回答6:
gem 'win32-security', '~> 0.3.1' if (RbConfig::CONFIG['host_os'] =~ /mswin|mingw|cygwin/)
That works pretty well for me.
回答7:
A variation of @ffoeg's answer worked for me, and handles all windows environments, whereas just using RUBY_PLATFORM=~ /win32/
didn't work:
if RUBY_PLATFORM =~ /mswin|mingw|cygwin/i
gem 'windows-only'
else
gem 'non-windows'
end
I agree that it's not ideal to have different gemfiles, however since I'm using unicorn
to serve my Jekyll blog on Heroku, so I need gem unicorn
- and this relies on kgio
which several sources have confirmed is virtually impossible to install on windows...
来源:https://stackoverflow.com/questions/8421321/does-using-platforms-in-your-gemfile-work