2010-06-07 9 views
11

deux bibliothèques partagées liba.so et libb.so. liba.so utilise libb.so. Tous les fichiers c sont compilés avec -fPIC. La liaison utilise -shared. Quand nous appelons dlopen sur liba.so, il ne trouve pas de symboles dans libb.so ... nous obtenons l'erreur "symbole non défini". Nous pouvons dlopen libb.so sans erreurs. Nous savons que liba trouve libb parce que nous n'obtenons pas d'erreur de fichier introuvable. Nous obtenons un fichier introuvable erreur lorsque nous supprimons libb.so. Nous avons essayé -lutil et pas de chance.Bibliothèque partagée Linux qui utilise une bibliothèque partagée non définie

Des idées ????

oh oui. Mise à jour: Nous utilisons rpath lors de la liaison liba afin qu'il puisse trouver libb.

ldd liba.so retourne:.

linux-gate.so.1 => (0xffffe000) 
libb.so => ./libb.so (0xf6ef9000) <-------- LIBB 
libutil.so.1 => /lib/libutil.so.1 (0xf6ef5000) 
libdl.so.2 => /lib/libdl.so.2 (0xf6ef1000) 
libm.so.6 => /lib/libm.so.6 (0xf6ec9000) 
libpthread.so.0 => /lib/libpthread.so.0 (0xf6eb1000) 
librt.so.1 => /lib/librt.so.1 (0xf6ea8000) 
libc.so.6 => /lib/libc.so.6 (0xf6d62000) 
/lib/ld-linux.so.2 (0x007d0000) 

est-il Significat qu'il n'y a pas # à la fin de libb ???

+1

Vous dites: vous avez créé deux bibliothèques (-fPIC -shared), liba.so et libb.so. liba.so est lié de façon dinamique (ou devrait l'être ...) avec libb.so et l'utilise. Dans un programme X, vous essayez dlopen sur libb.so et tout va bien; un autre programme de test Y essaye de dlopen liba.so mais il échoue, néanmoins vous savez liba.so trouve libb.so correctement puisque vous avez essayé de supprimer libb.so et un autre problème est soulevé ... options que vous utilisez pour dlopen? – ShinTakezou

+0

Vous avez tout compris. Pour le moment, nous n'utilisons aucune option, car dlopen est appelé à partir d'un programme sur lequel nous n'avons aucun contrôle. – johnnycrash

+0

Que dit la commande 'ldd liba.so'? –

Répondre

16

Vous pouvez facilement vérifier où libb.so devrait être avec ldd commande:

$ ldd liba.so 
    linux-gate.so.1 => (0xb77b0000) 
    libb.so.1 => not found 
    libstdc++.so.6 => /usr/lib/libstdc++.so.6 (0xb75b6000) 
    libgcc_s.so.1 => /lib/libgcc_s.so.1 (0xb7572000) 
    libc.so.6 => /lib/i686/cmov/libc.so.6 (0xb742b000) 
    /lib/ld-linux.so.2 (0xb77b1000) 

Si c'est not found, chemin de libb.so doit être ajouté à /etc/ld.so.conf ou variable shell LD_LIBRARY_PATH.

Une autre façon est de définir rpath dans le liba.so lui-même - il est fondamentalement codage en dur son chemin donc lorsque le binaire est démarré l'éditeur de liens dynamique sait où chercher les bibliothèques partagées.

Si rpath est défini pas d'abord une recherche dans LD_LIBRARY_PATH, puis les chemins mentionnés dans /etc/ld.so.conf (ou /etc/ld.so.conf.d/). Après avoir ajouté à ls.so.conf ne pas oublier d'exécuter /sbin/ldconfig

éditeur de liens dynamiques recherche les bibliothèques partagées dépendantes par leur soname (si elle est définie) - si soname est pas définie (avec -Wl, -soname, pour libb.so.1 exemple), il sera recherché par le nom de la bibliothèque. Exemple: libb.so.1.0 est votre bibliothèque actuelle, ayant soname - libb.so.1. Vous auriez normalement la structure des fichiers suivants:

libb.so -> libb.so.1 
libb.so.1 -> libb.so.1.0 
libb.so.1.0 

libb.so et libb.so.1 sont des liens symboliques.

Vous créez généralement un lien vers libb.so, lors de la création d'une application ou d'une autre bibliothèque, en fonction de libb.so.

gcc -shared -Wl,-soname,liba.so.1 -o liba.so.1.2 -L/libb/path -lb 

Lorsque l'application est lancée (ou dlopen est exécuté - votre cas) - l'éditeur de liens dynamique recherchera le fichier avec le nom libb.so.1 - la soname de la bibliothèque dépendante, si le soname est réglé, pas libb.so.

C'est pourquoi vous avez besoin de ce lien symbolique libb.so.1, pointant vers la bibliothèque actuelle.

Si vous utilisez ld.so.conf et ldconfig, il créera le lien symbolique avec le nom de soname, pointant vers le fichier de bibliothèque, si ce lien symbolique est manquant.

Vous pouvez voir la page de manuel ld-linux pour plus d'informations utiles.


Si la bibliothèque se trouve, mais quelques-uns des symboles sont manquants, mais essayez d' libb.so avec -Wl,--no-undefined l'option

gcc -shared -Wl,-soname,libb.so.1 -Wl,--no-undefined -o libb.so.1.2 

Il devrait vous donner une erreur si vous avez manqué de définir un symbole.

+0

, nous utilisons rpath. Nous sommes assez sûrs de trouver la bibliothèque, car nous avons essayé d'exécuter l'application après la suppression de libb et nous obtenons un fichier introuvable. Lorsque nous utilisons libb, nous obtenons une erreur de symbole indéfinie. – johnnycrash

+0

Bravo pour rpath .... mais pas notre problème. – johnnycrash

+0

je n'aurais peut-être pas compris la partie sur soname ... pouvez-vous clarifier un peu? – johnnycrash

0

N'oubliez pas que l'ordre des bibliothèques (tous les arguments -lxxx) est important (au moins dans gcc) lorsque vous liez toutes vos bibliothèques & pour générer votre exécutable.

exemple court:

LIBS = -L. -ltest1 -ltest2

OBJS = code1.o code2.o

$ gcc (LIBS) $ (OBJS) -o mysoft

qui peut échouer dans certains cas, alors que

gcc $ (OBJS) -o mysoft $ (LIBS)

ne sera pas

Questions connexes