在我安装好 Ruby on Rails 后,使用
rails new
命令新建一个项目,然后切换到项目下执行 rails server
,出现如下错误:sam@linux-qo4p:~/front/ror|master⚡⇒ rails server
Ignoring RedCloth-4.2.9 because its extensions are not built. Try: gem pristine RedCloth-4.2.9
Ignoring posix-spawn-0.3.9 because its extensions are not built. Try: gem pristine posix-spawn-0.3.9
Ignoring rdiscount-2.1.7.1 because its extensions are not built. Try: gem pristine rdiscount-2.1.7.1
/usr/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:54:in `require': cannot load such file -- bundler/setup (LoadError)
from /usr/lib/ruby/site_ruby/2.0.0/rubygems/core_ext/kernel_require.rb:54:in `require'
from /home/sam/front/ror/config/boot.rb:4:in `<top (required)>'
from bin/rails:3:in `require_relative'
from bin/rails:3:in `<main>'
这似乎是我把 openSUSE 系统从 13.1 升级到 13.2 后才出现的错误。
我的情况里,尝试错误信息中的提示方法
gem pristine RedCloth
并不能消除以上错误。
最后的解决办法是:
gem pristine --all
- 切换到项目根目录,
bundle install
再次跑
rails server
,可以正常启动不报错。此后,rails new
新建的项目也不再报错。参考
When you install Ruby gems that have native extensions (usually developed in C and compiled) sometimes that extension binds itself to a system library, for example Nokogiri with LibXML.
After a library upgrade (security minor update, or a full system upgrade), your gem has to be rebuilt to use the new library’s interface.
Most of the times, the gem will continue to work just fine, put will print a message like this :
1
| WARNING: Nokogiri was built against LibXML version 2.7.8, but has dynamically loaded 2.8.0 |
So how can we rebuild the gem?
You could upgrade the gem’s version in your application’s dependency specifications (usually Bundler’s
Gemfile
), and redeploy your app. It’s ok, but what if you don’t want to change the version?
The best way would be to rebuild the existing gem and restart your app. There is a
gem pristine --all
command available. I’ve tried it but it didn’t solve my issue. Maybe the rebuild process doesn’t change the libraries paths, or something else. If you know about this, let me know too ;)
You could uninstall the gem and redeploy your app. If you’re using a deployment mechanism that checks for dependencies, it will reinstall the gem and build it against the latest library. But in the meantime, the gem is missing and your app might break.
You could finally briefly uninstall the gem and reinstall it. On a modern server, it’s a matter of tens of seconds.
The usual steps :
1
2
3
4
5
6
7
8
9
10
| $ gem list | grep nokogiri nokogiri (1.5.11) $ gem uninstall --executables --ignore-dependencies nokogiri Removing nokogiri Successfully uninstalled nokogiri-1.5.11 $ gem install nokogiri -v 1.5.11 Fetching: nokogiri-1.5.11.gem (100%) Building native extensions. This could take a while... Successfully installed nokogiri-1.5.11 1 gem installed |
The
--executables --ignore-dependencies
flags on uninstall
disable confirmation for removing the gem executable(s) and dependency warnings.
[Edit] The
--ignore-dependencies
flag is better than --force
. It is also compatible with Rubygems 1.8.
If you’re using something Bundler and Capistrano, there is an additional issue ; the gems are not installed in your traditional Ruby paths, they are in your application’s shared directory.
Here is the gem environment of one of my users :
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
| $ gem env RubyGems Environment: - RUBYGEMS VERSION: 2.2.2 - RUBY VERSION: 2.1.1 (2014-02-24 patchlevel 76) [x86_64-linux] - INSTALLATION DIRECTORY: /home/jlecour/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0 - RUBY EXECUTABLE: /home/jlecour/.rbenv/versions/2.1.1/bin/ruby - EXECUTABLE DIRECTORY: /home/jlecour/.rbenv/versions/2.1.1/bin - SPEC CACHE DIRECTORY: /home/jlecour/.gem/specs - RUBYGEMS PLATFORMS: - ruby - x86_64-linux - GEM PATHS: - /home/jlecour/.rbenv/versions/2.1.1/lib/ruby/gems/2.1.0 - /home/jlecour/.gem/ruby/2.1.0 - GEM CONFIGURATION: - :update_sources => true - :verbose => true - :backtrace => false - :bulk_threshold => 1000 - "gem" => "--no-rdoc --no-ri" - :sources => ["http://rubygems.org"] - REMOTE SOURCES: - SHELL PATH: - /home/jlecour/.rbenv/versions/2.1.1/bin - /home/jlecour/.rbenv/libexec - /home/jlecour/.rbenv/plugins/rbenv-vars/bin - /home/jlecour/.rbenv/plugins/ruby-build/bin - /home/jlecour/.rbenv/shims - /home/jlecour/.rbenv/bin - /home/jlecour/bin - /usr/local/bin - /usr/bin - /bin - /usr/local/games - /usr/games |
But my application’s gems are in
/home/jlecour/apps/example/shared/bundle/ruby/2.1.0/
To tell the
gem
command to use this location, you have to set the GEM_HOME
environment variable for each call (or exporting it at the beginning, but remember to set it back after)
The sequence becomes this :
1
2
3
4
5
6
7
8
9
10
11
12
| $ export GEM_HOME=/home/jlecour/apps/example/shared/bundle/ruby/2.1.0/ $ gem list | grep nokogiri nokogiri (1.5.11) $ gem uninstall --executables --ignore-dependencies nokogiri Removing nokogiri Successfully uninstalled nokogiri-1.5.11 $ gem install nokogiri -v 1.5.11 Fetching: nokogiri-1.5.11.gem (100%) Building native extensions. This could take a while... Successfully installed nokogiri-1.5.11 1 gem installed $ unset GEM_HOME |
Then you just have to restart your application。