2011-07-09 26 views
25

Tengo una biblioteca compartida utilizada por otra aplicación fuera de mi control que requiere objetos * .so. Mi biblioteca utiliza sqlite3, que necesita estar enlazado estáticamente con él (absolutamente necesito un binario autónomo).C++ Biblioteca compartida vinculada estáticamente

Cuando intento compilar y vincular 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 

Lo que se recompilación con -fPIC relacionado con? Mi código o CRT?

Ya he intentado compilar mi objeto con -fPIC con el mismo resultado.

Gracias.

EDIT:

no parece estar relacionada con SQLite3 El problema.

escribí una biblioteca simple de una sola línea que no hace nada que recopila y enlaces de esta manera:

g++ -c -fPIC -o bar.o bar.cpp 
g++ -shared -o bar.so bar.o 

pero no como este:

g++ -c -fPIC -o bar.o bar.cpp 
g++ -static -shared -o bar.so bar.o 

El problema parece estar relacionado con la CRT (crtbeginT.o). ¿Se supone que debo recompilar GCC --with-pic o algo así?

+0

Esto es un poco confuso. ¿Está intentando simplemente vincular su biblioteca a una biblioteca sqlite estática, o está tratando de hacer otra cosa también? – nos

+0

PIC = Código independiente de posición, requerido para libs compartidas (en la mayoría de las arquitecturas, supongo) – sehe

+0

@nos Intentando unir mi biblioteca compartida con sqlite3.a – Petr

Respuesta

35

Usted no debe usar la bandera -static al crear una biblioteca compartida, es para crear ejecutables enlazados estáticamente.

Si solo tiene una versión estática de la biblioteca, puede simplemente vincularla usando . Pero si hay una versión dinámica (.so) y otra estática, el vinculador preferirá la dinámica.

Para indicar al vinculador que elija el elemento estático, proporcione al vinculador la marca -Bstatic y haga que vuelva a cambiar a vínculos dinámicos para otras cosas (como libc y soporte de tiempo de ejecución dinámico) con -Bdynamic. Es decir, que utilice las banderas:

-Wl,-Bstatic -lsqlite3 -Wl,-Bdynamic 

Alternativly, sólo puede especificar la ruta completa del archivo .a, por ejemplo, /usr/lib/libsqlite3.a en lugar de cualquier indicador de compilador/enlazador.

Con el ld de GNU, también puede usar -l:libsqlite3.a en lugar de . Esto forzará el uso del archivo de biblioteca libsqlite3.a en lugar de libsqlite3.so, que el vinculador prefiere de manera predeterminada.

Recuerde asegurarse de que el archivo .a se haya compilado con el indicador -fpic, de lo contrario, normalmente no puede incrustarlo en una biblioteca compartida.

+0

Tengo el mismo problema aquí y no sé cómo compilar una biblioteca compartida que NO se vincule dinámicamente con personal dependiente de la distribución, como libc/libstdC++ - '-Bstatic' proporcionar una biblioteca compartida vinculada dinámicamente. Maravillosamente, usando MinGW en Windows puedo vincular .dll con '-static' correctamente (dependiendo solo de windows dlls pero no de mingw). ¿Hay alguna manera de unir .so estáticamente? – Nick

+0

No. Las bibliotecas compartidas de Unix funcionan de forma muy diferente a las de windows dlls. – nos

+0

El truco -l: libsqlite3.a también funciona en eclipse cdt. Ingrese: libsqlite3.a en Propiedades-> C/C++ Build-> Configuración-> GCC C Linker-> Bibliotecas y la compilación enlazará estáticamente contra la biblioteca. – zztops

7

Cualquier código que de alguna manera llegue a una biblioteca dinámica debe ser reubicable. Significa que todo lo que está vinculado con su .so, no importa ni estática ni dinámicamente, debe compilarse con -fPIC. Específicamente, la biblioteca estática sqlite también se debe compilar con -fPIC.

detalles de lo PIC medios están aquí: http://en.wikipedia.org/wiki/Position-independent_code

+0

He recompilado sqlite3 --with-pic, pero el resultado sigue siendo el mismo ... – Petr

+0

Publique los comandos completos de enlace que realiza para que podamos analizar más) – vines

+0

Vea la publicación original. – Petr

0

Tuve el mismo problema. Aparentemente, "estático" no es lo mismo que "estático". Cambié a -Bstatic y todo funcionó.

Cuestiones relacionadas