Comment faire en sorte que les liens faibles fonctionnent avec GCC?

Il semble y avoir 3 façons de dire à GCC de relier un symbole par un lien faible

  • __atsortingbute__((weak_import))
  • __atsortingbute__((weak))
  • #pragma weak symbol_name

Aucun de ces travaux pour moi:

 #pragma weak asdf extern void asdf(void) __atsortingbute__((weak_import, weak)); ... { if(asdf != NULL) asdf(); } 

Je reçois toujours une erreur de lien comme celle-ci:

  Symboles non définis:
   "_asdf", référencé à partir de:
       _asdf $ non_lazy_ptr dans ccFA05kN.o
 ld: symbole (s) non trouvé
 collect2: ld a renvoyé 1 état de sortie 

J’utilise GCC 4.0.1 sur OS X 10.5.5. Qu’est-ce que je fais mal?

J’ai juste étudié la question et pensé que d’autres pourraient être intéressées par mes découvertes.

Les liens faibles avec faible_import ne fonctionnent vraiment que dans les bibliothèques dynamics. Vous pouvez le faire fonctionner avec des liens statiques (en spécifiant -undefined dynamic_lookup comme suggéré ci-dessus), mais ce n’est pas une idée si chaude. Cela signifie qu’aucun symbole non défini ne sera détecté avant l’exécution. C’est quelque chose que j’éviterais personnellement dans le code de production.

Voici une session de terminal Mac OS X montrant comment le faire fonctionner:

Voici fc

 int f(int n) { return n * 7; } 

Voici whatnof.c

 #include  #include  extern int f (int) __atsortingbute__((weak_import)); int main() { if(f == NULL) printf("what, no f?\n"); else printf("f(8) is %d\n", f(8)); exit(0); } 

Créez une bibliothèque dynamic à partir de fc:

 $ cc -dynamiclib -o f.dylib fc 

Comstackz et liez contre la bibliothèque dynamic, listez les bibliothèques dynamics.

 $ cc -o whatnof whatnof.c f.dylib $ otool -L whatnof whatnof: f.dylib (compatibility version 0.0.0, current version 0.0.0) /usr/lib/libSystem.B.dylib (compatibility version 1.0.0, current version 125.2.0) 

Exécuter quoi pour voir ce qui se passe:

 $ whatnof f(8) is 56 

Remplacez maintenant f.dylib par une bibliothèque vide (pas de symboles):

 $ mv f.dylib f.dylib.real $ touch null.c $ cc -dynamiclib -o f.dylib null.c 

Exécutez la même chose pour voir ce qui se passe:

 $ whatnof what, no f? 

L’idée de base (ou “cas d’utilisation”) de faible_import est de vous permettre de créer des liens avec un ensemble de bibliothèques dynamics (partagées), mais d’exécuter le même code avec des versions antérieures des mêmes bibliothèques. Vous pouvez vérifier les fonctions par rapport à NULL pour voir si elles sont sockets en charge dans la bibliothèque dynamic particulière sur laquelle le code est en cours d’exécution. Cela semble faire partie du modèle de développement de base pris en charge par Xcode. J’espère que cet exemple est utile. cela m’a aidé à me sentir à l’aise avec cette partie de la conception de Xcode.

Ajoutez -Wl,-flat_namespace,-undefined,dynamic_lookup à la ligne du compilateur gcc que vous utilisez pour -Wl,-flat_namespace,-undefined,dynamic_lookup le lien final.

Vous devez définir la variable MACOSX_DEPLOYMENT_TARGET sur 10.2 ou ultérieure. Consultez la documentation d’Apple et sa note technique sur les liens faibles.

Du manuel de la documentation gcc:

faible

L’atsortingbut faible entraîne l’émission de la déclaration sous forme de symbole faible plutôt que global. Cela est principalement utile pour définir des fonctions de bibliothèque qui peuvent être remplacées dans le code utilisateur, bien que cela puisse également être utilisé avec des déclarations autres que des fonctions. Les symboles faibles sont pris en charge pour les cibles ELF, ainsi que pour les cibles a.out lors de l’utilisation de l’assembleur et de l’éditeur de liens GNU.

ce qui signifie qu’un object est légitimé pour écraser un symbole faible (défini dans un autre object / bibliothèque) sans générer d’erreurs au moment du lien. Ce qui n’est pas clair, c’est si vous liez ou non la bibliothèque avec le symbole faible . Il semble que vous n’ayez pas défini le symbole à la fois et que la bibliothèque ne soit pas correctement liée.