2010-04-29 20 views
14

Je transfère un système existant de Windows vers Linux. La construction est structurée avec plusieurs bibliothèques statiques. J'ai rencontré une erreur de liaison où un symbole (défini dans libA) ne pouvait pas être trouvé dans un objet de libB. La ligne de liaison ressemblaitComment gérer les dépendances récursives entre bibliothèques statiques utilisant le lieur binutils?

g ++ test_obj.o test de -LA -LB

Le problème étant bien sûr qu'au moment où l'éditeur de liens trouve le symbole a besoin de Liba, il a déjà passé par, et ne rescanne pas, donc il fait simplement des erreurs même si le symbole est là pour la prise. Mon idée initiale était bien sûr d'échanger simplement le lien (à -lB -lA) de sorte que libA soit balayé par la suite, et que tous les symboles manquants dans libB qui sont dans libA soient récupérés. Mais alors je trouve qu'il y a effectivement une dépendance récursive entre libA et libB! Je suppose que l'éditeur de liens Visual C++ gère cela d'une certaine façon (est-ce que cela réanalyse par défaut?).

façons de faire face à ce que j'ai pris en compte:

  • Utilisez des objets partagés. Malheureusement, ceci n'est pas souhaitable du point de vue de la nécessité de se conformer à la PIC (c'est un code sensible à la performance et perdre% ebx pour que le GOT soit vraiment douloureux), et les objets partagés ne sont pas nécessaires.

  • Construire un méga ar ar de tous les objets, en évitant le problème.

  • Restructurer le code pour éviter la dépendance récursive (ce qui est évidemment la bonne chose à faire, mais j'essaye de faire ce port avec des changements minimes).

Avez-vous d'autres idées pour faire face à cela? Y a-t-il un moyen de convaincre l'éditeur de liens binutils d'effectuer des reprises de bibliothèques qu'il a déjà examinées lorsqu'il manque un symbole?

Répondre

18

Il suffit de faire ceci:

g++ test_obj.o -lA -lB -lA  -o test 

Lorsque l'éditeur de liens lit la première Liba sur la ligne de commande, il va jeter l'objet/symboles dans ce que Noone a dépendu encore, par exemple tous les symboles ont besoin de libB mais pas test_obj.o. Donc, vous le faites juste lire à nouveau la libA, et il récupérera également ces symboles.

+2

Cette question et cette réponse est un excellent exemple d'une solution élégante vous regarder en face ... Il se lit presque comme la punchline d'une blague ...: – dicroce

10

Alors que @nos fournit une solution simple, elle ne s'adapte pas lorsque plusieurs bibliothèques sont impliquées et que les dépendances mutuelles sont plus complexes. Pour trier les problèmes ld fournit --start-group archives --end-group.

Dans votre cas particulier:

g++ test_obj.o --start-group -lA -lB --end-group -o test 
+0

g ++ test_obj.o -Wl, - groupe de démarrage -lA -lB -Wl, - groupe de fin -o test – yokto