que - C++ Biblioteca compartida enlazada estáticamente
librerias estandar de c++ (3)
Cualquier código que de alguna manera se abra camino en una biblioteca dinámica debe ser reubicable. Significa que todo lo que está vinculado con su .so, sin importar estática o dinámicamente, debe compilarse con -fPIC
. Específicamente, la biblioteca de sqlite
estática también debe compilarse con -fPIC
.
Los detalles de lo que significa PIC están aquí: http://en.wikipedia.org/wiki/Position-independent_code
Tengo una biblioteca compartida utilizada por otra aplicación fuera de mi control que requiere objetos * .so. Mi biblioteca hace uso de sqlite3, que necesita estar enlazado estáticamente (necesito un archivo binario autónomo).
Cuando intento compilar y enlazar mi biblioteca:
-fpic -flto -pthread -m64
-flto -static -shared
Termino con el siguiente error:
/usr/bin/ld: /usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.6.1/crtbeginT.o: relocation R_X86_64_32 against `__DTOR_END__'' can not be used when making a shared object; recompile with -fPIC
/usr/local/lib/gcc/x86_64-unknown-linux-gnu/4.6.1/crtbeginT.o: could not read symbols: Bad value
collect2: ld returned 1 exit status
¿Con qué está relacionado la recompilación con -fPIC ? Mi código o CRT?
Ya he intentado compilar mi objeto con -fPIC con el mismo resultado.
Gracias.
EDITAR:
El problema no parece estar relacionado con SQLite3.
Escribí una simple biblioteca de una línea que no hace nada, que compila y enlaza así:
g++ -c -fPIC -o bar.o bar.cpp
g++ -shared -o bar.so bar.o
pero no así:
g++ -c -fPIC -o bar.o bar.cpp
g++ -static -shared -o bar.so bar.o
El problema parece estar relacionado con CRT (crtbeginT.o). ¿Se supone que debo recompilar GCC - with-pic o algo?
No debe usar el indicador -static
al crear una biblioteca compartida, es para crear ejecutables enlazados estáticamente.
Si solo tiene una versión estática de la biblioteca, solo puede vincularla usando -lsqlite3
. Pero si hay una versión dinámica (.so) y una versión estática, el enlazador preferirá la versión dinámica.
Para indicarle al vinculador que elija el estático, -Bstatic
al vinculador el indicador -Bstatic
y haga que vuelva al enlace dinámico para otras cosas (como libc y el soporte de tiempo de ejecución dinámico) con -Bdynamic
. Es decir, usas las banderas:
-Wl,-Bstatic -lsqlite3 -Wl,-Bdynamic
Como alternativa, solo puede especificar la ruta completa del archivo .a, por ejemplo, /usr/lib/libsqlite3.a
lugar de cualquier indicador de compilador / vinculador.
Con GNU ld, también puede usar -l:libsqlite3.a
lugar de -lsqlite3
. Esto forzará el uso del archivo de biblioteca libsqlite3.a
lugar de libsqlite3.so
, que el enlazador prefiere de forma predeterminada.
Recuerde asegurarse de que el archivo .a se haya compilado con el indicador -fpic
, de lo contrario, normalmente no podrá incrustarlo en una biblioteca compartida.
Yo tuve el mismo problema. Aparentemente -static no es lo mismo que -Bstatic. Cambié a -Estático y todo funcionó.