J'ai un problème pour lier une bibliothèque partagée avec g ++. Cela me donne un avertissement comme:
hidden symbol XXX in YYY is referenced by DSO /usr/lib/...
J'ai lu quelques questions connexes sur des problèmes particuliers, mais je veux le comprendre dans son ensemble - que signifie cet avertissement et quelle est la cause:
Qu'est-ce qu'un DSO?
A [~ # ~] dso [~ # ~] est un Dynamic Shared Object, ou moins formellement une bibliothèque partagée .
Qu'est-ce qu'un symbole caché?
A symbole caché est un symbole (c'est-à-dire le nom de la fonction ou de l'objet de données) qui a été compilé avec liaison cachée, par ex. selon la déclaration (spécifique du CCG):
int x __attribute__ ((visibility ("hidden")));
Si x
est défini dans un DSO, la liaison dynamique ne peut pas le référencer à partir d'un autre DSO. L'éditeur de liens peut voir x
(ce n'est pas static
), mais il n'est pas disponible pour le lien dynamique. Documentation ici
Comment peut-il être référencé, s'il est caché?
Cela ne peut pas être le cas, et c'est ce qui vous prévient. Par exemple. l'avertissement de temps de liaison:
le symbole caché `stat 'dans /usr/lib/libc_nonshared.a(stat.oS) est référencé par DSO
vous indique qu'un DSO dans la liaison fait référence au symbole stat
et que l'éditeur de liens peut localiser une définition de stat
dans /usr/lib/libc_nonshared.a
, mais (évidemment) cette définition n'est pas dans le DSO qui la référence et ne peut pas être référencée à partir de ce DSO, car elle est masquée.
Vous obtenez ce problème si le problème DSO n'a pas été créé correctement pour une utilisation en tant que DSO. Voir cet exemple et suivez les suivis de la solution.
Suite pour les suivis OP
Si le symbole caché est déjà référencé par certains DSO, alors pourquoi le problème est-il avec DSO?
L'éditeur de liens dit:
Le DSO X
contient une référence au symbole S
. Je peux trouver une définition du symbole S
est un autre module lié Y
, mais cette définition ne sera pas disponible pour satisfaire la référence dans X
dynamiquement (ie lors de l'exécution) parce que S
a un lien caché dans Y
.
Je peux confirmer que le problème vient d'un objet non partagé [...] [mais] je ne cache pas explicitement ces symboles dans mon objet non partagé.
Vous ne pouvez pas avoir explicitement marqué de symboles cachés dans l'objet non partagé. Selon la façon dont il a été construit, les symboles peuvent être masqués par défaut, sauf s'ils sont explicitement marqués sinon.
Supposons que l'objet non partagé soit libnonshared.a
et le symbole prétendument caché est foo
. Courir:
objdump -t libnonshared.a
pour obtenir des informations sur les symboles dans libnonshared.a
. Dans la sortie, recherchez l'entrée pour foo
. Contient-il la balise .hidden
? - par exemple.
0000000000000000 g F .text 000000000000000b .hidden foo
Cette entrée indique que foo
est un symbole global (marqué g
- c'est pourquoi l'éditeur de liens est capable de le voir) mais il est masqué pour dynamique liaison.
Si cela s'avère être le cas, vous devez aller corriger la version de libnonshared.a
pour qu'il ne cache pas foo
. Sinon, je suis perplexe.