314 votes

Quelles sont les différences entre .so et .dylib sous macOS ?

.dylib est l'extension de bibliothèque dynamique sur macOS, mais je n'ai jamais su clairement quand je ne pouvais/ne devais pas utiliser un objet partagé traditionnel unix .so.

Certaines des questions que je me pose :

  • Au niveau conceptuel, quelles sont les principales différences entre .so et .dylib ?
  • Quand puis-je/doit-on utiliser l'un plutôt que l'autre ?
  • Trucs et astuces de compilation (par exemple, le remplacement de gcc -shared -fPIC, puisque cela ne fonctionne pas sur osx)

296voto

Miles Points 12977

Le format de fichier objet Mach-O utilisé par Mac OS X pour les exécutables et les bibliothèques fait la distinction entre bibliothèques partagées y modules chargés dynamiquement . Utilisez otool -hv some_file pour voir le type de fichier de some_file .

Les bibliothèques partagées de Mach-O ont le type de fichier MH_DYLIB et portent l'extension .dylib. Ils peuvent être liés avec les drapeaux habituels de l'éditeur de liens statiques, par ex. -lfoo pour libfoo.dylib. Ils peuvent être créés en passant l'option -dynamiclib au compilateur. ( -fPIC est la valeur par défaut et n'a pas besoin d'être spécifiée).

Les modules chargeables sont appelés "bundles" dans le langage de Mach-O. Ils ont le type de fichier MH_BUNDLE . Ils peuvent porter n'importe quelle extension ; l'extension .bundle est recommandée par Apple, mais la plupart des logiciels portés utilisent .so pour des raisons de compatibilité. Typiquement, vous utiliserez les bundles pour plug-ins qui étendent une application ; dans ce cas, le bundle sera lié au binaire de l'application pour accéder à l'API exportée de l'application. Ils peuvent être créés en passant le paramètre -bundle au compilateur.

Les dylibs et les bundles peuvent être chargés dynamiquement à l'aide de la commande dl API (par exemple dlopen , dlclose ). Il n'est pas possible de lier les bundles comme s'il s'agissait de bibliothèques partagées. Cependant, il est possible qu'un bundle soit lié à des bibliothèques partagées réelles ; celles-ci seront chargées automatiquement lorsque le bundle sera chargé.

Historiquement, les différences étaient plus importantes. Dans Mac OS X 10.0, il n'y avait aucun moyen de charger dynamiquement des bibliothèques. Un ensemble d'API dyld (par ex. NSCreateObjectFileImageFromFile , NSLinkModule ) ont été introduits avec la 10.1 pour charger et décharger les paquets, mais ils ne fonctionnaient pas pour les dylibs. A dlopen La bibliothèque de compatibilité qui fonctionne avec les bundles a été ajoutée en 10.3 ; en 10.4, dlopen a été réécrit pour être une partie native de dyld et a ajouté le support du chargement (mais pas du déchargement) des dylibs. Enfin, 10.5 a ajouté la prise en charge de l'utilisation de dlclose avec dylibs et a déprécié les API de dyld.

Sur les systèmes ELF comme Linux, les deux utilisent le même format de fichier ; tout morceau de code partagé peut être utilisé comme une bibliothèque et pour le chargement dynamique.

Enfin, sachez que dans Mac OS X, "bundle" peut también font référence à des répertoires dont la structure est normalisée et qui contiennent du code exécutable et les ressources utilisées par ce code. Il existe un certain chevauchement conceptuel (notamment avec les "paquets chargeables" comme les plugins, qui contiennent généralement du code exécutable sous la forme d'un paquet Mach-O), mais il ne faut pas les confondre avec les paquets Mach-O dont il est question ci-dessus.

Références supplémentaires :

2 votes

Merci pour ce commentaire détaillé :) Si je comprends bien, si je charge un bundle à partir d'un autre bundle (i.e. le chemin est app -> bundle A -> bundle B), alors le bundle B ne sera pas capable de voir les symboles du bundle A ? Et si oui, existe-t-il des moyens de résoudre ce problème ? Je crois que je viens de trouver la solution : stackoverflow.com/questions/4193539/

6 votes

@noloader : -dynamiclib est un drapeau GCC. Il permet au compilateur de passer -dylib à ld.

0 votes

Mise à jour de l'URL de la page de manuel de ld sur Mac OSX : manpages.info/macosx/ld.1.html

31voto

Zachary Kraus Points 81

La différence entre .dylib et .so sur mac os x est la façon dont ils sont compilés. Pour les fichiers .so, vous utilisez -shared et pour les .dylib, vous utilisez -dynamiclib. Les fichiers .so et .dylib sont interchangeables en tant que fichiers de bibliothèque dynamique et ont un type comme DYLIB ou BUNDLE. Voici la lecture de différents fichiers qui le montrent.

libtriangle.dylib:
Mach header
      magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
MH_MAGIC_64  X86_64        ALL  0x00       DYLIB    17       1368   NOUNDEFS DYLDLINK TWOLEVEL NO_REEXPORTED_DYLIBS

libtriangle.so:
Mach header
      magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
MH_MAGIC_64  X86_64        ALL  0x00       DYLIB    17       1256   NOUNDEFS DYLDLINK TWOLEVEL NO_REEXPORTED_DYLIBS

triangle.so:
Mach header
      magic cputype cpusubtype  caps    filetype ncmds sizeofcmds      flags
MH_MAGIC_64  X86_64        ALL  0x00      BUNDLE    16       1696   NOUNDEFS DYLDLINK TWOLEVEL

Si les deux sont équivalents sur Mac OS X, c'est pour des raisons de rétrocompatibilité avec d'autres programmes UNIX OS qui compilent dans le type de fichier .so.

Remarques sur la compilation : que vous compiliez un fichier .so ou un fichier .dylib, vous devez insérer le chemin d'accès correct dans la bibliothèque dynamique pendant l'étape de liaison. Pour ce faire, ajoutez -install_name et le chemin du fichier à la commande de liaison. Si vous ne le faites pas, vous rencontrerez le problème décrit dans cet article : La folie des bibliothèques dynamiques Mac (peut être en Fortran seulement) .

25voto

user2996950 Points 21

Juste une observation que je viens de faire en construisant du code naïf sur OSX avec cmake :

cmake ... -DBUILD_SHARED_LIBS=OFF ...

crée .donc fichiers

tandis que

cmake ... -DBUILD_SHARED_LIBS=ON ...

crée .dynlib des fichiers.

Peut-être que cela peut aider quelqu'un.

22voto

Loki Astari Points 116129

Le fichier .so n'est pas une extension de fichier UNIX pour la bibliothèque partagée.

Il se trouve que c'est un cas courant.

Vérifiez la ligne 3b à Page de la bibliothèque partagée ArnaudRecipes

En fait, .dylib est l'extension de fichier mac utilisée pour indiquer une librairie partagée.

9 votes

@ninefingers. C'est exact. Mais certains outils utiliseront des valeurs par défaut à moins que quelque chose ne soit très explicite. Par exemple, les compilateurs utiliseront l'extension de librairie partagée spécifique à leur plate-forme lorsque le drapeau -l<lib> est utilisé (le drapeau réel peut varier d'un compilateur à l'autre).

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X