gcc statique de la bibliothèque de liaison vs la liaison dynamique
Mon environnement de compilation est CentOS 5. J'ai une bibliothèque tierce appelée libcunit. Je l'ai installé avec les autotools et il génère à la fois libcunit.a
et libcunit.so
. J'ai ma propre application qui a des liens avec un tas de bibliothèques partagées. libcunit.a
est dans le répertoire courant et libcunit.so
et d'autres bibliothèques partagées sont dans /usr/local/lib/
. Quand je compile comme:
gcc -o test test.c -L. libcunit.a -L/usr/local/lib -labc -lyz
- Je obtenir un lien d'erreur:
libcunit.a(Util.o): In function `CU_trim_left':
Util.c:(.text+0x346): undefined reference to `__ctype_b'
libcunit.a(Util.o): In function `CU_trim_right':
Util.c:(.text+0x3fd): undefined reference to `__ctype_b'
Mais quand je compile avec .so
comme:
gcc -o test test.c -L/usr/local/lib -lcunit -labc -lyz
il compile fine et fonctionne très bien aussi.
Pourquoi donne-t-il erreur lorsque lié statiquement à libcunit.a
?
OriginalL'auteur bala1486 | 2013-04-16
Vous devez vous connecter pour publier un commentaire.
Le problème, c'est que votre
libcunit.a
a été construit sur un ancien système Linux, et repose sur des symboles qui ont été retiré delibc
(ces symboles ont été utilisés dansglibc-2.2
, et ont été retirés deglibc-2.3
de plus de 10 ans). Plus exactement, ces symboles ont étéhidden
. Ils sont mis à disposition pour la liaison dynamique pour les anciens binaires (commelibcunit.so
) mais pas de nouveau code peut lier statiquement (vous ne pouvez pas créer un nouveau fichier exécutable ou une bibliothèque partagée qui y fait référence).Vous pouvez observer ce comme suit:
OriginalL'auteur Employed Russian
N'avais pas remarqué que le
libcunit.a
est réellement dans votre cas et le problème avec linakge est plutôt dans la CUnit bibliothèque elle-même. Emploi russe est tout à fait juste, et il ne parle pas de binaires précompilés ici. Nous comprenons que vous avez construit vous-même. Cependant, CUinit lui-même semble être en s'appuyant sur le symbole deglibc
qui n'est pas disponible pour la liaison statique plus. Par conséquent, vous n'avez que 2 options:Néanmoins, ma recommandation au sujet de votre style d'une liaison statique s'applique toujours.
-L.
est en général mauvaise pratique. CUnit est une 3ème partie de la bibliothèque et ne doit pas être placé dans le répertoire contenant les fichiers source de votre projet. Il devrait plutôt être installé de la même manière que la version dynamique, c'est à dire que vous avez de lalibcunit.so
dans/usr/local/lib
. Si vous souhaitez d'approvisionnementprefix
à Autotools sur l'étape de configuration de CUnit, puis Autotools serait tout installer correctement. Donc, si vous souhaitez lier statiquement à CUnit, pensez à le faire sous la forme suivante:Russie: Où voulez-vous voir ma réponse à aborder le problème de "bibliothèque de la commande"? Le projet de ligne de commande est juste un copier-coller de l'OP de la ligne de commande avec certains modifié/ajouté drapeaux, mais pas changé de couplage de l'ordre.
Vous n'avez pas besoin
-Wl,-Bstatic
si vous listelibcunit.a
directement (OP).OriginalL'auteur Alexander Shukaev