I'm trying to build a UDF library using rake:
task :compile do
system("gcc -L/usr/local/lib -lgmp -lpaillier `mysql_config --cflags` -c -fPIC #{FILE}.c")
system("ar -x /usr/local/lib/libpaillier.a")
system("gcc -shared *.o -L/usr/lib/x86_64-linux-gnu/ -lgmp -o #{LIBFILE}")
system("sudo mv #{LIBFILE} /usr/lib/mysql/plugin/")
end
but I'm getting this error:
/usr/bin/ld: paillier.o: relocation R_X86_64_32 against `.rodata.str1.1' can not be used when making a shared object; recompile with -fPIC
paillier.o: error adding symbols: Bad value
collect2: error: ld returned 1 exit status
Here:
gcc -L/usr/local/lib -lgmp -lpaillier `mysql_config --cflags` -c -fPIC #{FILE}.c
you are compiling an object file whose name will be the value of #{FILE}.o
-
let's say it is aa.o
- and you are compiling it with Position-Independent Code
(-fPIC
). Your linker flags:
-L/usr/local/lib -lgmp -lpaillier
serve no purpose here and are ignored because no linking is being done.
Here:
ar -x /usr/local/lib/libpaillier.a
you are extracting all of the object files from the static library /usr/local/lib/libpaillier.a
. There is in fact just
one object file in the library, paillier.o
Here:
gcc -shared *.o -L/usr/lib/x86_64-linux-gnu/ -lgmp -o #{LIBFILE}
you are building a shared library whose name will be the value of #{LIBFILE}
- let's say it is libfoo.so
- linking the object files aa.o
, paillier.o
,
plus libgmp
.
Extracting the object file paillier.o
from libpaillier.a
to link it with libfoo.so
achieves nothing different from not extracting it and simply linking
libpaillier.a
itself, i.e nothing different from:
gcc -shared #{FILE}.o -L/usr/local/lib -lpaillier -L/usr/lib/x86_64-linux-gnu/ -lgmp -o #{LIBFILE}
And the linkage library paths:
-L/usr/local/lib -L/usr/lib/x86_64-linux-gnu/
are superflous because both of those paths are default linker search paths on your system.
But a shared library must be built entirely from PIC object code. aa.o
was compiled
with -fPIC
, in your first step. However, paillier.o
was not not. So the linkage fails and the linker
advises you that paillier.o
must be recompiled with -fPIC
.
So do that:-
Delete your existing /usr/local/lib/libpaillier.a
and /usr/local/include/paillier.h
Go back to your libpaillier
source directory (where you built it first time).
Clean it up:
$ make clean
Reconfigure the autotools build system to compile PIC code:
$ ./configure CFLAGS=-fPIC [and whatever other options you used before]
Rebuild:
$ make
Reinstall:
$ sudo make install
Now you again have a header /usr/local/include/paillier.h
and
a static library /usr/local/lib/libpaillier.a
but this time
the paillier.o
in the library is PIC code.
Then you can build your plugin with:
task :compile do
system("gcc `mysql_config --cflags` -c -fPIC #{FILE}.c")
system("gcc -shared #{FILE}.o -lpaillier -lgmp -o #{LIBFILE}")
system("sudo mv #{LIBFILE} /usr/lib/mysql/plugin/")
end