/usr/bin/ld: ./libudns.a(udns_resolver.o): relocation R_X86_64_32 against `dns_defctx' can not be used when making a shared object; recompile with -fPIC

Michael Tokarev mjt at tls.msk.ru
Tue Feb 8 22:27:40 MSK 2011


08.02.2011 22:12, Iñaki Baz Castillo wrote:
> Hi, I've finished my Ruby C extension for udns, and it works really well !!
> I want to thank Michael Tokarev for all your help (and patience).
> 
> I just have a problem due to the fact that libudns is no longer part
> of Linux distros (they have old 0.0.9 version). I know your reasons,
> however it would be great if you would package it again :)

Not all distros have it at all - for example it's not part of Debian.

> Well, using Debian libudns0 and libudns-dev packages I can compile my
> Ruby C extension perfectly (just need to include "-ludns" when
> generating my .so). But this is not longer an option for the future so
> I must include the sources of udns within my Ruby gem, so when
> somebody runs "gem install em-udns" it downloads my gem and the Ruby
> Gem mechanism would compile udns, generate a libudns.a, and my Ruby C
> extension would compile against it to create a final em-udns.so which
> can be loaded in a Ruby program at runtime.
> 
> Other option would be compile udns dynamically and generate a
> libudns.so, but this would require it to be installed under usual
> /usr/lib/ or /usr/local/lib/ and that's not cool for the instalation
> of a Ruby gem (Ruby gems can also be installed in user home with no
> root permissions).
> 
> So let's go with the libudns.a option:
> 
> - I compile (make) udns, generate libudns.a and copy it to my Ruby C
> folder along with udns.h.
> - Then I generate the ruby C extension Makefile.
> - And run make. Note that my system is 64 bits. I get this error:
> 
> gcc -I. -I/usr/include/ruby-1.9.1/x86_64-linux
> -I/usr/include/ruby-1.9.1/ruby/backward -I/usr/include/ruby-1.9.1 -I.
>  -fPIC -fno-strict-aliasing -g -g -O2 -fPIC  -o em-udns.o -c em-udns.c
> gcc -shared -o em_udns_ext.so em-udns.o -L. -L/usr/lib -L.  -rdynamic
> -Wl,-export-dynamic   -lruby-1.9.1 -ludns  -lpthread -lrt -ldl -lcrypt
> -lm   -lc
> /usr/bin/ld: ./libudns.a(udns_resolver.o): relocation R_X86_64_32
> against `dns_defctx' can not be used when making a shared object;
> recompile with -fPIC
> ./libudns.a: could not read symbols: Bad value
> collect2: ld returned 1 exit status
> make: *** [em_udns_ext.so] Error 1

It suggests you what to do.

When compiling it tells you to use additional option, -- -fPIC, which
stands for Position-Independent Code, which is a base for any shared
object, which will be loaded at runtime at a "random" address.

You can try running `make sharedlib' in the udns source directory --
this will produce a series of .lo files, just like it produces a
bunch of .o files for static library.  You grab these .lo files
and produce a static library from them -- libudns.a, like this:

  rm -f libudns.a
  ar r libudns.a *.lo

This is not perfect, but will work for your case.  Regular static
library will not - because you're producing shared object from it,
and regular static library is meant to be used to produce a simple
executable.

Another alternative is to re-implement the makefile using the same
build system as uses - this is trivial, you just need to take a list
of files from udns Makefile.

/mjt


More information about the udns mailing list