Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mac OS: LoadError: Could not open library 'vips' #141

Closed
Nakilon opened this issue Oct 11, 2017 · 21 comments
Closed

Mac OS: LoadError: Could not open library 'vips' #141

Nakilon opened this issue Oct 11, 2017 · 21 comments

Comments

@Nakilon
Copy link
Contributor

Nakilon commented Oct 11, 2017

So I did brew upgrade vips that poured the vips-8.5.8_2.el_capitan and now require vips (the gem is the latest one) cause:

LoadError: Could not open library 'vips': dlopen(vips, 5): image not found.
Could not open library '/usr/local/lib/libvips.dylib': dlopen(/usr/local/lib/libvips.dylib, 5): Library not loaded: @rpath/libpoppler.71.dylib
  Referenced from: /usr/local/opt/poppler/lib/libpoppler-glib.8.dylib
  Reason: image not found
	from /Users/nakilon/.gem/gems/ffi-1.9.18/lib/ffi/library.rb:147:in `block in ffi_lib'
	from /Users/nakilon/.gem/gems/ffi-1.9.18/lib/ffi/library.rb:100:in `map'
	from /Users/nakilon/.gem/gems/ffi-1.9.18/lib/ffi/library.rb:100:in `ffi_lib'
	from /Users/nakilon/.gem/gems/ruby-vips-2.0.7/lib/vips.rb:466:in `<module:Vips>'
	from /Users/nakilon/.gem/gems/ruby-vips-2.0.7/lib/vips.rb:457:in `<top (required)>'
$ ls -l /usr/local/lib/libvips.dylib
lrwxr-xr-x  1 nakilon  admin  40 11 окт 19:17 /usr/local/lib/libvips.dylib -> ../Cellar/vips/8.5.8_2/lib/libvips.dylib
$ ls -l /usr/local/lib/libpoppler.dylib 
lrwxr-xr-x  1 nakilon  admin  45 11 окт 19:17 /usr/local/lib/libpoppler.dylib -> ../Cellar/poppler/0.60.1/lib/libpoppler.dylib

Ruby is native to this OS: 2.0.0p648

The thing I've noticed about brew is that now it drags some portable Ruby 2.3 -- not sure if that's relevant.

@hmistry
Copy link

hmistry commented Oct 12, 2017

Have a look at #130 and try the suggestions... I think it's a bad install configuration issue and you need to track down where it went wrong.

@jcupitt
Copy link
Member

jcupitt commented Oct 12, 2017

I tried again here and it seems to be working on sierra at least:

==> Downloading https://homebrew.bintray.com/bottles/vips-8.5.8_2.sierra.bottle.
==> Downloading from https://akamai.bintray.com/89/89fdabb07d18ac3cf22448e1bbb6f
######################################################################## 100.0%
==> Pouring vips-8.5.8_2.sierra.bottle.tar.gz
🍺  /usr/local/Cellar/vips/8.5.8_2: 188 files, 12.7MB
john@katamata ~ $ gem uninstall ruby-vips
Successfully uninstalled ruby-vips-2.0.6
john@katamata ~ $ gem install ruby-vips
Fetching: ruby-vips-2.0.7.gem (100%)
Successfully installed ruby-vips-2.0.7
Parsing documentation for ruby-vips-2.0.7
Installing ri documentation for ruby-vips-2.0.7
Done installing documentation for ruby-vips after 1 seconds
1 gem installed
john@katamata ~ $ irb
irb(main):001:0> require 'vips'
=> true
irb(main):002:0> x = Vips::Image.black 10, 10
=> #<Image 10x10 uchar, 1 bands, b-w>
irb(main):003:0> 

@Nakilon
Copy link
Contributor Author

Nakilon commented Oct 12, 2017

$ which vips
/usr/local/bin/vips
$ vips --version
vips-8.5.8-Fri Oct  6 06:09:10 BST 2017
$ brew --prefix vips
/usr/local/opt/vips

$ gem uninstall ruby-vips
Select gem to uninstall:
 1. ruby-vips-1.0.3
 2. ruby-vips-2.0.7
 3. All versions
> 3
Successfully uninstalled ruby-vips-1.0.3
Successfully uninstalled ruby-vips-2.0.7
$ gem install ruby-vips
Fetching: ruby-vips-2.0.7.gem (100%)
Successfully installed ruby-vips-2.0.7
Parsing documentation for ruby-vips-2.0.7
Installing ri documentation for ruby-vips-2.0.7
1 gem installed

$ irb
irb(main):001:0> require "vips"
LoadError: Could not open library 'vips': dlopen(vips, 5): image not found.
Could not open library '/usr/local/lib/libvips.dylib': dlopen(/usr/local/lib/libvips.dylib, 5): Library not loaded: @rpath/libpoppler.71.dylib
  Referenced from: /usr/local/opt/poppler/lib/libpoppler-glib.8.dylib
  Reason: image not found
	from /Users/nakilon/.gem/gems/ffi-1.9.18/lib/ffi/library.rb:147:in `block in ffi_lib'
	from /Users/nakilon/.gem/gems/ffi-1.9.18/lib/ffi/library.rb:100:in `map'
	from /Users/nakilon/.gem/gems/ffi-1.9.18/lib/ffi/library.rb:100:in `ffi_lib'
	from /Users/nakilon/.gem/gems/ruby-vips-2.0.7/lib/vips.rb:466:in `<module:Vips>'
	from /Users/nakilon/.gem/gems/ruby-vips-2.0.7/lib/vips.rb:457:in `<top (required)>'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rubygems/core_ext/kernel_require.rb:135:in `require'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rubygems/core_ext/kernel_require.rb:135:in `rescue in require'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rubygems/core_ext/kernel_require.rb:144:in `require'
	from (irb):1
	from /usr/bin/irb:12:in `<main>'

@Nakilon
Copy link
Contributor Author

Nakilon commented Oct 12, 2017

Putting debug prints into ffi I see it loads libglib and libgobject as dylibs from /usr/local/lib/ but fails to load libvips.

$ file /usr/local/lib/libvips.dylib
/usr/local/lib/libvips.dylib: Mach-O 64-bit dynamically linked shared library x86_64

What is poppler? Maybe it's smth wrong with it?

$ file /usr/local/lib/libpoppler
libpoppler-cpp.0.3.0.dylib   libpoppler-cpp.dylib         libpoppler-glib.8.dylib      libpoppler.71.0.0.dylib      libpoppler.dylib
libpoppler-cpp.0.dylib       libpoppler-glib.8.9.0.dylib  libpoppler-glib.dylib        libpoppler.71.dylib  

UPD: in the brew install vips it poured the poppler-0.60.1, not 71 -- not sure if that matters.

@Nakilon
Copy link
Contributor Author

Nakilon commented Oct 12, 2017

Switching back via $ brew switch vips 8.5.8 does not help:

$ vips --version
dyld: Library not loaded: /usr/local/opt/poppler/lib/libpoppler-glib.8.dylib
  Referenced from: /usr/local/bin/vips
  Reason: Incompatible library version: vips requires version 18.0.0 or later, but libpoppler-glib.8.dylib provides version 8.0.0
Trace/BPT trap: 5

@Nakilon
Copy link
Contributor Author

Nakilon commented Oct 17, 2017

Applying patch from #144 (usr instead of opt) had no effect.

Maybe its libpoppler-glib that can't find the proper path to poppler.dylib?

Wanted to debug paths that process tries to open but dtruss and dtrace are broken since El Capitan.

@Nakilon
Copy link
Contributor Author

Nakilon commented Oct 20, 2017

Weird stuff. Looking for a way to debug I found such tools as dtrace and similar. To make it work on modern Mac OS you have to avoid the SIP (that security thing that protects /usr/bin). One of the ways to do this is to copy the binary from /usr/bin to any another folder. So I've copied ruby and irb to another folder, edited the shebang in irb, ran it and guess what -- it does require "vips" and loads images with no problem.

P.S.: LD_LIBRARY_PATH=/usr/local/lib does not help.
The iibpoppler dylib is this:

-r--r--r--  1 nakilon  admin  2196424 17 окт 05:00 /usr/local/Cellar/poppler/0.60.1/lib/libpoppler.71.0.0.dylib

@Nakilon
Copy link
Contributor Author

Nakilon commented Oct 20, 2017

Probably related: ros2/ros2#391 (comment)

@Nakilon
Copy link
Contributor Author

Nakilon commented Oct 21, 2017

So as workaround I've decided to copy a ruby executable to another directory -- for example, a working directory of where I need to run things. Like this:

$ sudo cp /usr/bin/ruby ./
$ chmod 500 ./ruby

Here is how I made things work:

IRB

If you do which irb you'll see that it's a ruby script /usr/bin/irb that has hardcoded shebang #!/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/ruby so instead of irb you have to do:

$ ./ruby irb

RSPEC

which rspec gives me /Users/nakilon/.gem/bin/rspec and there we see the #!/usr/bin/env ruby that means you don't have to patch it, just:

$ PATH=`pwd`:$PATH rspec

RAKE

Running rspec via rake is tricky -- it is doing it in another way and seems to use the system ruby. How to check it? The only working way to know the exact path to executable by PID on Mac OS I've found is https://stackoverflow.com/a/14805946/322020 so you compile it and put the tool nearby. You can see it's working by:

$ ruby -e 'puts `./pathfind #{Process.pid}`'
proc 19893: /usr/bin/ruby
$ PATH=`pwd`:$PATH ruby -e 'puts `pathfind #{Process.pid}`'
proc 19897: /Users/nakilon/.../ruby
$ PATH=`pwd`:$PATH /usr/bin/env ruby -e 'puts `pathfind #{Process.pid}`'
proc 19900: /Users/nakilon/.../ruby

Now at the bottom of vips issue backtrace we see from /Users/nakilon/.gem/gems/rspec-core-3.5.3/exe/rspec:4. Here its content:

#!/usr/bin/env ruby

require 'rspec/core'
RSpec::Core::Runner.invoke

Right after shebang you add the following line for debug:

puts __FILE__, `/Users/nakilon/.../pathfind #{Process.pid}`

Now when you run the rake again you see:

/Users/nakilon/.gem/gems/rspec-core-3.5.3/exe/rspec
proc 19849: /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/ruby

that means shebang is ignored. Open the /usr/bin/rake and add the

require "byebug"
byebug

right before the Rake.application.run -- moving down with step and next commands you'll eventually get to:

[74, 83] in /Users/nakilon/.gem/gems/rspec-core-3.5.3/lib/rspec/core/rake_task.rb
   74:       # @private
   75:       def run_task(verbose)
   76:         command = spec_command
   77:         puts command if verbose
   78: 
=> 79:         return if system(command)
   80:         puts failure_message if failure_message
   81: 
   82:         return unless fail_on_error
   83:         $stderr.puts "#{command} failed" if verbose
(byebug) command
/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/ruby -I/Users/nakilon/.gem/gems/rspec-support-3.5.0/lib:/Users/nakilon/.gem/gems/rspec-core-3.5.3/lib /Users/nakilon/.gem/gems/rspec-core-3.5.3/exe/rspec --pattern spec/\*\*\{,/\*/\*\*\}/\*_spec.rb

where the spec_command was:

   141:       def spec_command
   142:         cmd_parts = []
   143:         cmd_parts << RUBY
   144:         cmd_parts << ruby_opts
   145:         cmd_parts << rspec_load_path

The RUBY constant isn't declared at the moment the byebug starts but it appears immediately after you step into Rake.application.run. If you do the

$ grep -rI "RUBY =" /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/

you'll find the RUBY = ENV['RUBY'] || File.join( in file_utils.rb that is required by /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rake.rb. So the solution is:

$ RUBY=`pwd`/ruby rake

if the default rake task is rspec, and:

$ ./ruby `which rake` my_custom_rask

for simple custom tasks.

@jcupitt
Copy link
Member

jcupitt commented Oct 21, 2017

Thank you for writing this @Nakilon, it's very helpful.

I guess another solution would be to recommend the homebrew Ruby, is that right?

@Nakilon
Copy link
Contributor Author

Nakilon commented Oct 21, 2017

Since the issue didn't exist earlier, I think smth is broken and can be fixed. Maybe some updated dependency does not meet modern Mac OS practices. That's not nice to force people to use another Ruby or disable SIP.

@Nakilon
Copy link
Contributor Author

Nakilon commented Nov 20, 2017

Update to large comment.

This

bundle exec ./ruby `which irb`

seems to stop working if you install rbenv. In this case you should do:

bundle exec ./ruby /usr/bin/irb

since the which irb now points to bash script that obviously can't be interpreted by ruby, while the real location can be known by rbenv which irb.

Same about rake:

./ruby `rbenv which rake` mytask

@ioquatix
Copy link
Member

ioquatix commented Jan 7, 2018

I'm having the same/similar problem.

@ioquatix
Copy link
Member

ioquatix commented Jan 7, 2018

From what I've read, it seems plausible that DYLD_LIBRARY_PATH no longer works with SIP which is on by default. Therefore, the only solution AFAIK is to specify the full path of the library or install it into a standard location.

@ioquatix
Copy link
Member

ioquatix commented Jan 7, 2018

Okay, by specifying explicit paths to ffi_lib for glib-2.0, gobject-2.0 and vips to /opt/local/lib/libX.dylib it worked. So, it's clearly a search path issue, but it was working before upgrading to high Sierra.

@Nakilon
Copy link
Contributor Author

Nakilon commented Jan 7, 2018

@ioquatix with what Ruby distribution did it work for you? System one, or rbenv, or rvm?

@ioquatix
Copy link
Member

ioquatix commented Jan 7, 2018

I'm using rvm.

@jcupitt
Copy link
Member

jcupitt commented Jan 11, 2018

The ruby-ffi issue on this has an interesting idea:

ffi/ffi#461

They are suggesting that when SIP is on, executables started from /usr/bin automatically have all environment variables stripped. This means DYLD_* is removed, and so ffi can't find the library.

To fix this, simply make a link from /usr/bin/ruby to /usr/local/bin/ruby:

ln -s /usr/bin/ruby /usr/local/bin/ruby

and it might all start working. Worth a try.

@Nakilon
Copy link
Contributor Author

Nakilon commented Jan 11, 2018

Sadly it doesn't work for rspec and irb because:

$ head -1 `which rspec`
#!/usr/bin/env ruby
$ head -1 /usr/bin/irb
#!/System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/bin/ruby

And even without that it does not work for me:

$ /usr/local/bin/ruby -e "require 'vips'"
/Users/nakilon/.gem/gems/ffi-1.9.18/lib/ffi/library.rb:147:in `block in ffi_lib': Could not open library 'vips': dlopen(vips, 5): image not found. (LoadError)
Could not open library '/usr/local/lib/libvips.dylib': dlopen(/usr/local/lib/libvips.dylib, 5): Library not loaded: @rpath/libpoppler.71.dylib
  Referenced from: /usr/local/opt/poppler/lib/libpoppler-glib.8.dylib
  Reason: image not found
	from /Users/nakilon/.gem/gems/ffi-1.9.18/lib/ffi/library.rb:100:in `map'
	from /Users/nakilon/.gem/gems/ffi-1.9.18/lib/ffi/library.rb:100:in `ffi_lib'
	from /Users/nakilon/.gem/gems/ruby-vips-2.0.9/lib/vips.rb:466:in `<module:Vips>'
	from /Users/nakilon/.gem/gems/ruby-vips-2.0.9/lib/vips.rb:457:in `<top (required)>'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rubygems/core_ext/kernel_require.rb:135:in `require'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rubygems/core_ext/kernel_require.rb:135:in `rescue in require'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rubygems/core_ext/kernel_require.rb:144:in `require'
	from -e:1:in `<main>'

And about rake:

$ RUBY=/usr/local/bin/ruby rake
/Users/nakilon/.gem/gems/ffi-1.9.18/lib/ffi/library.rb:147:in `block in ffi_lib': Could not open library 'vips': dlopen(vips, 5): image not found. (LoadError)
Could not open library '/usr/local/lib/libvips.dylib': dlopen(/usr/local/lib/libvips.dylib, 5): Library not loaded: @rpath/libpoppler.71.dylib
  Referenced from: /usr/local/opt/poppler/lib/libpoppler-glib.8.dylib
  Reason: image not found
	from /Users/nakilon/.gem/gems/ffi-1.9.18/lib/ffi/library.rb:100:in `map'
	from /Users/nakilon/.gem/gems/ffi-1.9.18/lib/ffi/library.rb:100:in `ffi_lib'
	from /Users/nakilon/.gem/gems/ruby-vips-2.0.9/lib/vips.rb:466:in `<module:Vips>'
	from /Users/nakilon/.gem/gems/ruby-vips-2.0.9/lib/vips.rb:457:in `<top (required)>'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rubygems/core_ext/kernel_require.rb:135:in `require'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rubygems/core_ext/kernel_require.rb:135:in `rescue in require'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rubygems/core_ext/kernel_require.rb:144:in `require'
	from /Users/nakilon/_/assembla/gems/dhash-vips/lib/dhash-vips.rb:2:in `<top (required)>'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rubygems/core_ext/kernel_require.rb:55:in `require'
	from /System/Library/Frameworks/Ruby.framework/Versions/2.0/usr/lib/ruby/2.0.0/rubygems/core_ext/kernel_require.rb:55:in `require'
	from /Users/nakilon/_/assembla/gems/dhash-vips/spec/_spec.rb:1:in `<top (required)>'
	from /Users/nakilon/.gem/gems/rspec-core-3.5.3/lib/rspec/core/configuration.rb:1435:in `load'
	from /Users/nakilon/.gem/gems/rspec-core-3.5.3/lib/rspec/core/configuration.rb:1435:in `block in load_spec_files'
	from /Users/nakilon/.gem/gems/rspec-core-3.5.3/lib/rspec/core/configuration.rb:1433:in `each'
	from /Users/nakilon/.gem/gems/rspec-core-3.5.3/lib/rspec/core/configuration.rb:1433:in `load_spec_files'
	from /Users/nakilon/.gem/gems/rspec-core-3.5.3/lib/rspec/core/runner.rb:100:in `setup'
	from /Users/nakilon/.gem/gems/rspec-core-3.5.3/lib/rspec/core/runner.rb:86:in `run'
	from /Users/nakilon/.gem/gems/rspec-core-3.5.3/lib/rspec/core/runner.rb:71:in `run'
	from /Users/nakilon/.gem/gems/rspec-core-3.5.3/lib/rspec/core/runner.rb:45:in `invoke'
	from /Users/nakilon/.gem/gems/rspec-core-3.5.3/exe/rspec:4:in `<main>'

@Nakilon
Copy link
Contributor Author

Nakilon commented Mar 5, 2018

Upgraded macOS from El Captain to High Sierra -- it comes with Ruby 2.3.3. And issue seems to be gone.

@Nakilon Nakilon closed this as completed Mar 5, 2018
@caioabe
Copy link

caioabe commented Jan 31, 2022

This worked for me:
Macos M1
Rbenv
Ruby 3.0.1
Rails 7.0.1

Just ran arch -x86_64 brew install vips and the action_text successfully printed my jpg in trix editor content.

For those who don't know what arch -x86_64 is, take a look at:
https://en.wikipedia.org/wiki/Rosetta_(software)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants