web-dev-qa-db-fra.com

C++ Bibliothèque partagée liée statiquement

J'ai une bibliothèque partagée utilisée par une autre application indépendante de ma volonté qui nécessite des objets * .so. Ma bibliothèque utilise sqlite3 qui doit être liée statiquement avec elle (j'ai absolument besoin d'un binaire autonome).

Lorsque j'essaie de compiler et de lier ma bibliothèque:

-fpic -flto -pthread -m64
-flto -static -shared

Je me retrouve avec l'erreur suivante:

/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

Qu'est-ce que recompile avec -fPIC lié à? Mon code ou CRT?

J'ai déjà essayé de compiler mon objet avec -fPIC avec le même résultat.

Merci.

MODIFIER:

Le problème ne semble pas être lié à SQLite3.

J'ai écrit une simple bibliothèque d'une ligne ne faisant rien qui compile et relie comme ceci:

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

mais pas comme ça:

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

Le problème semble être lié au CRT (crtbeginT.o). Suis-je censé recompiler GCC - with-pic ou quoi que ce soit?

25
Petr

Vous ne devez pas utiliser l'indicateur -static lors de la création d'une bibliothèque partagée, c'est pour créer des exécutables liés statiquement.

Si vous ne possédez qu'une version statique de la bibliothèque, vous pouvez simplement la lier en utilisant -lsqlite3. Mais s'il existe à la fois une version dynamique (.so) et une version statique, l'éditeur de liens préférera la version dynamique.

Pour demander à l'éditeur de liens de choisir celui qui est statique, attribuez-lui l'indicateur -Bstatic et faites-le revenir à la liaison dynamique pour d'autres éléments (comme libc et le support d'exécution dynamique) avec -Bdynamic. C'est-à-dire que vous utilisez les drapeaux:

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

Alternativement, vous pouvez simplement spécifier le chemin complet du fichier .a, par exemple. /usr/lib/libsqlite3.a au lieu de tout indicateur de compilateur/éditeur de liens.

Avec le GNU ld, vous pouvez également utiliser -l:libsqlite3.a au lieu de -lsqlite3. Cela forcera l'utilisation du fichier de bibliothèque libsqlite3.a au lieu de libsqlite3.so, que l'éditeur de liens préfère par défaut.

N'oubliez pas de vous assurer que le fichier .a a été compilé avec l'indicateur -fpic, sinon vous ne pourrez normalement pas l'intégrer dans une bibliothèque partagée.

37
nos

Tout code susceptible d’être introduit dans une bibliothèque dynamique doit pouvoir être déplacé. Cela signifie que tout ce qui est lié à votre .so, que ce soit de manière statique ou dynamique, doit être compilé avec -fPIC. Plus précisément, la bibliothèque statique sqlite doit également être compilée avec -fPIC.

Les détails de ce que signifie PIC sont ici: http://fr.wikipedia.org/wiki/Position-independent_code

7
vines

J'ai eu le même problème. Apparemment, -static n'est pas la même chose que -Bstatic. Je suis passé à -Bstatic et tout a fonctionné. 

0
Dre