The Subversion Ruby bindings and the 'relocation R_X86_64_32' error

22 Jul 2009

I was setting up some servers with the Beanstalk guys and was building the Subversion Ruby bindings - you know, the ones that use SWIG. All was well until I got to make swig-rb. That resulted in an error which I will present in its entirety for easier Googling:

$ make swig-rb
cd subversion/bindings/swig/ruby/libsvn_swig_ruby && /bin/sh /home/beanstalk/src/subversion-1.5.5/libtool \
--tag=CC --silent --mode=link gcc  -g -O2  -g -O2 -pthread    -rpath /usr/local/lib -lruby-static -o \
libsvn_swig_ruby-1.la  swigutil_rb.lo ../../../../../subversion/libsvn_client/libsvn_client-1.la \
../../../../../subversion/libsvn_wc/libsvn_wc-1.la ../../../../../subversion/libsvn_delta/libsvn_delta-1.la \
../../../../../subversion/libsvn_subr/libsvn_subr-1.la /usr/local/apache2/lib/libaprutil-1.la -lexpat \
/usr/local/apache2/lib/libapr-1.la -luuid -lrt -lcrypt  -lpthread -ldl 
/usr/bin/ld: /usr/local/lib/libruby-static.a(array.o): relocation R_X86_64_32 against `a local symbol' can 
not be used when making a shared object; recompile with -fPIC
/usr/local/lib/libruby-static.a: could not read symbols: Bad value
collect2: ld returned 1 exit status
make: *** [subversion/bindings/swig/ruby/libsvn_swig_ruby/libsvn_swig_ruby-1.la] Error 1

The problem is that the linker is looking for a shared object library and finding only a static library. The solution is to recompile Ruby with the --enable-shared and reinstall it. This will create a shared object library (lib/libruby.so.1.8.6) in addition to the static library (lib/libruby-static.a), and if you retry make swig-rb it'll work.

I'm used to seeing Ruby libraries that depend on underlying native code - e.g., libxml-ruby depends on the libxml2 headers and such being in place, the mysql gem depends on the MySQL client, etc. But the Subversion bindings are different - they come with Subversion and depend on Ruby being already installed. It kind of turns things around.

Why doesn't the Subversion autoconf script (or the Makefile?) detect that there's no shared object library and fail with a more helpful error? I'm not sure... but that would be nice.