blackwinter / rb-gsl

Ruby interface to the GNU Scientific Library [Ruby 2.x and GSL 1.16 compatible fork of the gsl gem]
https://blackwinter.github.io/rb-gsl
Other
27 stars 7 forks source link

rb-gsl underlinking narray? #4

Closed gengor closed 10 years ago

gengor commented 10 years ago

Hi Mr. Wille,

I believe the build system is underlinking narray when final linking rb_gsl.so. The gem builds and installs fine as long as ldflags in the Makefile does not include -Wl,--no-undefined. ldflags is (partially) derived from the underlying OS. Some Linux OSes enforce this check, Gentoo being one of them. If --no-undefined is enforced on the linker, it fails with the following:

linking shared-object rb_gsl.so
multiroots.o: In function `rb_gsl_multiroot_fdjacobian':
multiroots.c:(.text+0x14f1): undefined reference to `cNArray'
multiroots.o: In function `rb_gsl_multiroot_fsolver_set':
multiroots.c:(.text+0x2013): undefined reference to `cNArray'
multiroots.o: In function `rb_gsl_multiroot_fdfsolver_set':
multiroots.c:(.text+0x228b): undefined reference to `cNArray'
multiroots.o: In function `rb_gsl_multiroot_function_solve':
multiroots.c:(.text+0x25cb): undefined reference to `cNArray'
vector_double.o: In function `rb_gsl_vector_decimate':
vector_double.c:(.text+0x1243): undefined reference to `cNArray'
vector_double.o:vector_double.c:(.text+0x165f): more undefined references to `cNArray' follow
vector_double.o: In function `rb_gsl_vector_filescan_na':
vector_double.c:(.text+0x1676): undefined reference to `na_make_object'
vector_double.o: In function `rb_gsl_vector_normalize_bang':
vector_double.c:(.text+0x17c2): undefined reference to `cNArray'
vector_double.o: In function `rb_gsl_vector_normalize':
vector_double.c:(.text+0x1914): undefined reference to `cNArray'
vector_double.o: In function `Init_gsl_vector':
vector_double.c:(.text+0x646f): undefined reference to `cNArray'
dht.o: In function `rb_gsl_dht_xk_sample':
dht.c:(.text+0xc47): undefined reference to `cNArray'
dht.c:(.text+0xc88): undefined reference to `na_make_object'
...<snip - continues on quite a ways>

If we don't enforce --no-undefined and let the build succeed we get the following final linking:

# scanelf -n rb_gsl.so
 TYPE   NEEDED FILE
ET_DYN libgsl.so.0,libm.so.6,libruby19.so.1.9,libc.so.6 rb_gsl.so

The build error can be fixed by changing this line in extconf.rb:

$LOCAL_LIBS = " -L#{File.join(narray_config, 'src')}" + $LOCAL_LIBS

To:

$LOCAL_LIBS = " -L#{File.join(narray_config, 'src')} -l:narray.so" + $LOCAL_LIBS

This allows the final linking phase to succeed when -Wl,--no-undefined is in ldflags in the Makefile. Installation completes successfully. Now we get:

# scanelf -n rb_gsl.so
 TYPE   NEEDED FILE
ET_DYN /usr/local/lib64/ruby/gems/1.9.1/gems/narray-0.6.0.8/src/narray.so,libgsl.so.0,libm.so.6,libruby19.so.1.9,libc.so.6 rb_gsl.so
blackwinter commented 10 years ago

Done. Thanks!

Could you check before I'm going to release a new version?

gengor commented 10 years ago

Thanks for the quick response! Your fix appears to work just fine.

Cheers!

dsedivec commented 10 years ago

I think this fix (a8ce8f0cec5e688ec51332d5e225a7f14ead777a) broke the build for me on OS X. I make a gem from HEAD with rake gem and then try to install it with gem install. Here's the significant-looking parts near the end of the gem install failure:

linking shared-object gsl/gsl_native.bundle
ld: library not found for -l:narray.so
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [gsl_native.bundle] Error 1

I'm on OS X. Looks like it's using clang to build. Versions:

$ clang --version
Apple LLVM version 5.0 (clang-500.2.79) (based on LLVM 3.3svn)
Target: x86_64-apple-darwin12.5.0
Thread model: posix
$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.8.5
BuildVersion:   12F45
$ ruby --version
ruby 2.1.1p76 (2014-02-24 revision 45161) [x86_64-darwin12.0]

I've never seen a -l option in the format -l:narray.so. Perhaps clang doesn't support that?

blackwinter commented 10 years ago

Clang just passes the option to ld, which also seems to accept it. But the file is probably named narray.bundle instead of narray.so on your platform.

@gengor Is there a reason you made the file extension explicit? Would -lnarray work for you?

dsedivec commented 10 years ago

If I check out a8ce8f0cec5e688ec51332d5e225a7f14ead777a, replace -l:narray.so with -lnarray in ext/gsl/extconf.rb, make the gem with rake gem, and then try to install that gem into a directory where bundler has installed narray for me, I get the following error:

linking shared-object gsl/gsl_native.bundle
ld: library not found for -lnarray

I also tried -l:narray and -l:narray.bundle. They all produced the same error as above (with -lnarray replaced with whatever switch I was trying in that iteration).

I don't know anything about OS X .bundle files, but for what it's worth, I found this excerpt from a relatively old book called Mac OS X for Unix Geeks: "WARNING: You cannot link directly against a bundle. Instead, bundles must be dynamically loaded and unloaded by the dyld APIs."

blackwinter commented 10 years ago

Ok, thanks. I guess the easiest way out would be to add darwin to the guard and skip that flag on OS X altogether. Or maybe even the other way around and only add it on linux platforms.

blackwinter commented 10 years ago

I opted for the latter. It would be great if the two of you could test it one more time.

dsedivec commented 10 years ago

fa9ab3d2e031500832c2b31d9230fc9892fbfe03 seems to build and run for me fine on OS X 10.8.5, Ruby 2.1.1p76. Thanks!

blackwinter commented 10 years ago

Thanks for checking. Version 1.16.0.1 was released a few days ago.

blackwinter commented 10 years ago

FYI, I had to change the guard for adding narray.so to the list of files to link (see c2b4939 and #5). This will be released as 1.16.0.2 soon, unless someone objects.

rubyist2016 commented 8 years ago

There are no similar lines in the extconf.rb for this case http://stackoverflow.com/questions/35950494/rails-loaderror-undefined-symbol-cnarray-when-using-gsl