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

Problem with function visibility on Linux #3

Closed
le0pard opened this issue Mar 8, 2013 · 4 comments
Closed

Problem with function visibility on Linux #3

le0pard opened this issue Mar 8, 2013 · 4 comments

Comments

@le0pard
Copy link
Contributor

le0pard commented Mar 8, 2013

I have issue with https://github.com/le0pard/webp-ffi. Writting library by using ffi and ffi-compiler. Check my library by rspec.

My Rackfile:

require 'bundler/setup'
require 'rake'
require 'rake/clean'
require 'bundler/gem_tasks'
require 'rspec/core/rake_task'
require 'ffi-compiler/compile_task'

desc "compiler tasks"
namespace "ffi-compiler" do
  FFI::Compiler::CompileTask.new('ext/webp_ffi/webp_ffi') do |c|
    c.have_header?('stdio.h', '/usr/local/include')
    c.have_func?('puts')
    c.have_library?('z')
    c.have_header?('decode.h', '/usr/local/include')
    c.have_header?('encode.h', '/usr/local/include')
    c.have_func?('WebPDecoderConfig')
    c.have_func?('WebPGetInfo')
    c.have_library?('webp')
    c.cflags << "-arch x86_64" if c.platform.mac?
    c.ldflags << "-arch x86_64" if c.platform.mac?
  end
end
task :compile => ["ffi-compiler:default"]

desc "run specs"
task :spec do
  RSpec::Core::RakeTask.new
end

task :default => [:clean, :compile, :spec]

CLEAN.include('ext/**/*{.o,.log,.so,.bundle}')
CLEAN.include('lib/**/*{.o,.log,.so,.bundle}')
CLEAN.include('ext/**/Makefile')

Running on Mac OS:

$ rake                                                                                                                                                                                                      ruby-2.0.0-p0 master 1c3740c ✗
rm -r ext/webp_ffi/x86_64-darwin/util.o
rm -r ext/webp_ffi/x86_64-darwin/webp_ffi.o
rm -r ext/webp_ffi/x86_64-darwin/libwebp_ffi.bundle
rm -r ext/webp_ffi/x86_64-darwin/libwebp_ffi.bundle
rm -r ext/webp_ffi/x86_64-darwin/util.o
rm -r ext/webp_ffi/x86_64-darwin/webp_ffi.o
gcc-4.2 -fexceptions -O -fno-omit-frame-pointer -fno-strict-aliasing -arch x86_64 -DHAVE_PUTS=1 -DHAVE_STDIO_H=1 -o ext/webp_ffi/x86_64-darwin/util.o -c ext/webp_ffi/util.c
gcc-4.2 -fexceptions -O -fno-omit-frame-pointer -fno-strict-aliasing -arch x86_64 -DHAVE_PUTS=1 -DHAVE_STDIO_H=1 -o ext/webp_ffi/x86_64-darwin/webp_ffi.o -c ext/webp_ffi/webp_ffi.c
gcc-4.2 -bundle -o ext/webp_ffi/x86_64-darwin/libwebp_ffi.bundle ext/webp_ffi/x86_64-darwin/util.o ext/webp_ffi/x86_64-darwin/webp_ffi.o -fexceptions -arch x86_64 -lz -lwebp
/Users/leo/.rvm/rubies/ruby-2.0.0-p0/bin/ruby -S rspec ./spec/webp_ffi_spec.rb

WebpFfi
  calculate plus 100 by test
  #webp_size
    1.webp image size == [400, 301]
    2.webp image size == [386, 395]
    3.webp image size == [300, 300]
    4.webp image size == [2000, 2353]
    nil for non-webp image

Finished in 0.02231 seconds
6 examples, 0 failures

And running on Ubuntu 12.04:

$ rake
rm -r ext/webp_ffi/x86_64-linux/util.o
rm -r ext/webp_ffi/x86_64-linux/webp_ffi.o
rm -r ext/webp_ffi/x86_64-linux/libwebp_ffi.so
rm -r ext/webp_ffi/x86_64-darwin/libwebp_ffi.bundle
rm -r ext/webp_ffi/x86_64-darwin/util.o
rm -r ext/webp_ffi/x86_64-darwin/webp_ffi.o
gcc -fexceptions -O -fno-omit-frame-pointer -fno-strict-aliasing -fPIC -DHAVE_PUTS=1 -DHAVE_STDIO_H=1 -o ext/webp_ffi/x86_64-linux/util.o -c ext/webp_ffi/util.c
gcc -fexceptions -O -fno-omit-frame-pointer -fno-strict-aliasing -fPIC -DHAVE_PUTS=1 -DHAVE_STDIO_H=1 -o ext/webp_ffi/x86_64-linux/webp_ffi.o -c ext/webp_ffi/webp_ffi.c
gcc -shared -o ext/webp_ffi/x86_64-linux/libwebp_ffi.so ext/webp_ffi/x86_64-linux/util.o ext/webp_ffi/x86_64-linux/webp_ffi.o -fexceptions -lz -lwebp
/home/vagrant/.rvm/rubies/ruby-2.0.0-p0/bin/ruby -S rspec ./spec/webp_ffi_spec.rb
/home/vagrant/.rvm/gems/ruby-2.0.0-p0/gems/ffi-1.4.0/lib/ffi/library.rb:251:in `attach_function': Function 'WebPGetInfo' not found in [/vagrant/ext/webp_ffi/x86_64-linux/libwebp_ffi.so] (FFI::NotFoundError)
    from /vagrant/lib/webp_ffi/c.rb:3:in `<module:C>'
    from /vagrant/lib/webp_ffi/c.rb:2:in `<module:WebpFfi>'
    from /vagrant/lib/webp_ffi/c.rb:1:in `<top (required)>'
    from /vagrant/lib/webp_ffi.rb:11:in `require'
    from /vagrant/lib/webp_ffi.rb:11:in `<top (required)>'
    from /vagrant/spec/spec_helper.rb:3:in `require'
    from /vagrant/spec/spec_helper.rb:3:in `<top (required)>'
    from /vagrant/spec/webp_ffi_spec.rb:1:in `require'
    from /vagrant/spec/webp_ffi_spec.rb:1:in `<top (required)>'
    from /home/vagrant/.rvm/gems/ruby-2.0.0-p0/gems/rspec-core-2.13.0/lib/rspec/core/configuration.rb:819:in `load'
    from /home/vagrant/.rvm/gems/ruby-2.0.0-p0/gems/rspec-core-2.13.0/lib/rspec/core/configuration.rb:819:in `block in load_spec_files'
    from /home/vagrant/.rvm/gems/ruby-2.0.0-p0/gems/rspec-core-2.13.0/lib/rspec/core/configuration.rb:819:in `each'
    from /home/vagrant/.rvm/gems/ruby-2.0.0-p0/gems/rspec-core-2.13.0/lib/rspec/core/configuration.rb:819:in `load_spec_files'
    from /home/vagrant/.rvm/gems/ruby-2.0.0-p0/gems/rspec-core-2.13.0/lib/rspec/core/command_line.rb:22:in `run'
    from /home/vagrant/.rvm/gems/ruby-2.0.0-p0/gems/rspec-core-2.13.0/lib/rspec/core/runner.rb:80:in `run'
    from /home/vagrant/.rvm/gems/ruby-2.0.0-p0/gems/rspec-core-2.13.0/lib/rspec/core/runner.rb:17:in `block in autorun'
rake aborted!
/home/vagrant/.rvm/rubies/ruby-2.0.0-p0/bin/ruby -S rspec ./spec/webp_ffi_spec.rb failed
/home/vagrant/.rvm/gems/ruby-2.0.0-p0/gems/rspec-core-2.13.0/lib/rspec/core/rake_task.rb:156:in `run_task'
/home/vagrant/.rvm/gems/ruby-2.0.0-p0/gems/rspec-core-2.13.0/lib/rspec/core/rake_task.rb:124:in `block (2 levels) in initialize'
/home/vagrant/.rvm/gems/ruby-2.0.0-p0/gems/rspec-core-2.13.0/lib/rspec/core/rake_task.rb:122:in `block in initialize'
/home/vagrant/.rvm/gems/ruby-2.0.0-p0/bin/ruby_noexec_wrapper:14:in `eval'
/home/vagrant/.rvm/gems/ruby-2.0.0-p0/bin/ruby_noexec_wrapper:14:in `<main>'
Tasks: TOP => default => spec
(See full trace by running task with --trace)

What my configuration is invalid? I coudn't find problem. Thanks in advance.

P.S. If you want test my lib you should install Web-P lib https://developers.google.com/speed/webp/docs/compiling

@le0pard
Copy link
Contributor Author

le0pard commented Mar 8, 2013

The same problem you can see in Travis: https://travis-ci.org/le0pard/webp-ffi

@ghost
Copy link

ghost commented Mar 8, 2013

It looks like WebPGetInfo() is defined in libwebp, and not in your library.

It also looks like linux does not re-export symbols from shared lib dependencies when building that shared lib.

What you need to do, is explicitly load libwebp via FFI, as well as your wrapper.

You can either use another module, and extend FFI::Library inside it, then ffi_lib, attach_function, etc, OR you can just tack it on to the end of your ffi_lib call.

e.g.

ffi_lib FFI::Compiler::Loader.find('webp_ffi'), 'webp'

@le0pard
Copy link
Contributor Author

le0pard commented Mar 8, 2013

Thanks, but right now I have another error:

$ rake
rm -r ext/webp_ffi/x86_64-linux/util.o
rm -r ext/webp_ffi/x86_64-linux/webp_ffi.o
rm -r ext/webp_ffi/x86_64-linux/libwebp_ffi.so
rm -r ext/webp_ffi/x86_64-linux/libwebp_ffi.so
rm -r ext/webp_ffi/x86_64-linux/util.o
rm -r ext/webp_ffi/x86_64-linux/webp_ffi.o
gcc -fexceptions -O -fno-omit-frame-pointer -fno-strict-aliasing -fPIC -DHAVE_PUTS=1 -DHAVE_STDIO_H=1 -o ext/webp_ffi/x86_64-linux/util.o -c ext/webp_ffi/util.c
gcc -fexceptions -O -fno-omit-frame-pointer -fno-strict-aliasing -fPIC -DHAVE_PUTS=1 -DHAVE_STDIO_H=1 -o ext/webp_ffi/x86_64-linux/webp_ffi.o -c ext/webp_ffi/webp_ffi.c
gcc -shared -o ext/webp_ffi/x86_64-linux/libwebp_ffi.so ext/webp_ffi/x86_64-linux/util.o ext/webp_ffi/x86_64-linux/webp_ffi.o -fexceptions -lz -lwebp
/home/vagrant/.rvm/rubies/ruby-2.0.0-p0/bin/ruby -S rspec ./spec/webp_ffi_spec.rb
/home/vagrant/.rvm/gems/ruby-2.0.0-p0/gems/ffi-1.4.0/lib/ffi/library.rb:123:in `block in ffi_lib': Could not open library 'webp': webp: cannot open shared object file: No such file or directory. (LoadError)
Could not open library 'libwebp.so': libwebp.so: cannot open shared object file: No such file or directory
    from /home/vagrant/.rvm/gems/ruby-2.0.0-p0/gems/ffi-1.4.0/lib/ffi/library.rb:90:in `map'
    from /home/vagrant/.rvm/gems/ruby-2.0.0-p0/gems/ffi-1.4.0/lib/ffi/library.rb:90:in `ffi_lib'
    from /vagrant/lib/webp_ffi.rb:7:in `<module:C>'
    from /vagrant/lib/webp_ffi.rb:5:in `<module:WebpFfi>'
    from /vagrant/lib/webp_ffi.rb:4:in `<top (required)>'
    from /vagrant/spec/spec_helper.rb:3:in `require'
    from /vagrant/spec/spec_helper.rb:3:in `<top (required)>'
    from /vagrant/spec/webp_ffi_spec.rb:1:in `require'
    from /vagrant/spec/webp_ffi_spec.rb:1:in `<top (required)>'
    from /home/vagrant/.rvm/gems/ruby-2.0.0-p0/gems/rspec-core-2.13.0/lib/rspec/core/configuration.rb:819:in `load'
    from /home/vagrant/.rvm/gems/ruby-2.0.0-p0/gems/rspec-core-2.13.0/lib/rspec/core/configuration.rb:819:in `block in load_spec_files'
    from /home/vagrant/.rvm/gems/ruby-2.0.0-p0/gems/rspec-core-2.13.0/lib/rspec/core/configuration.rb:819:in `each'
    from /home/vagrant/.rvm/gems/ruby-2.0.0-p0/gems/rspec-core-2.13.0/lib/rspec/core/configuration.rb:819:in `load_spec_files'
    from /home/vagrant/.rvm/gems/ruby-2.0.0-p0/gems/rspec-core-2.13.0/lib/rspec/core/command_line.rb:22:in `run'
    from /home/vagrant/.rvm/gems/ruby-2.0.0-p0/gems/rspec-core-2.13.0/lib/rspec/core/runner.rb:80:in `run'
    from /home/vagrant/.rvm/gems/ruby-2.0.0-p0/gems/rspec-core-2.13.0/lib/rspec/core/runner.rb:17:in `block in autorun'
rake aborted!
/home/vagrant/.rvm/rubies/ruby-2.0.0-p0/bin/ruby -S rspec ./spec/webp_ffi_spec.rb failed
/home/vagrant/.rvm/gems/ruby-2.0.0-p0/gems/rspec-core-2.13.0/lib/rspec/core/rake_task.rb:156:in `run_task'
/home/vagrant/.rvm/gems/ruby-2.0.0-p0/gems/rspec-core-2.13.0/lib/rspec/core/rake_task.rb:124:in `block (2 levels) in initialize'
/home/vagrant/.rvm/gems/ruby-2.0.0-p0/gems/rspec-core-2.13.0/lib/rspec/core/rake_task.rb:122:in `block in initialize'
/home/vagrant/.rvm/gems/ruby-2.0.0-p0/bin/ruby_noexec_wrapper:14:in `eval'
/home/vagrant/.rvm/gems/ruby-2.0.0-p0/bin/ruby_noexec_wrapper:14:in `<main>'
Tasks: TOP => default => spec
(See full trace by running task with --trace)

But library exist:

$ ls -la /usr/local/lib/
total 4504
drwxr-xr-x  5 root root     4096 Mar  8 11:53 .
drwxr-xr-x 10 root root     4096 Jun  5  2012 ..
-rw-r--r--  1 root root  2914584 Mar  8 11:53 libwebp.a
-rwxr-xr-x  1 root root      956 Mar  8 11:53 libwebp.la
lrwxrwxrwx  1 root root       16 Mar  8 11:53 libwebp.so -> libwebp.so.4.0.1
lrwxrwxrwx  1 root root       16 Mar  8 11:53 libwebp.so.4 -> libwebp.so.4.0.1
-rwxr-xr-x  1 root root  1669468 Mar  8 11:53 libwebp.so.4.0.1
drwxr-xr-x  2 root root     4096 Mar  8 11:53 pkgconfig
drwxrwsr-x  4 root staff    4096 Mar  8 11:02 python2.7
drwxr-xr-x  3 root root     4096 Mar  8 11:42 site_ruby

@le0pard
Copy link
Contributor Author

le0pard commented Mar 8, 2013

I found the problem, thanks!

sudo ln -s /usr/local/lib/libwebp.* /usr/lib/

@le0pard le0pard closed this as completed Mar 8, 2013
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

1 participant