web-dev-qa-db-fra.com

Quelles sont les différences entre .so et .dylib sur osx?

.dylib est l’extension de bibliothèque dynamique sur OSX, mais il m’a jamais été précisé si je ne pouvais/ne devais pas utiliser un objet unix partagé traditionnel .so.

Certaines de mes questions:

  • Sur le plan conceptuel, quelles sont les principales différences entre .so et .dylib?
  • Quand puis-je/devrais-je utiliser l'un sur l'autre?
  • Trucs et astuces pour la compilation (par exemple, le remplacement de gcc -shared -fPIC, car cela ne fonctionne pas sous osx)
190
Trent Davies

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

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

Les modules chargeables sont appelés "paquets" dans le langage Mach-O. Ils ont le type de fichier MH_BUNDLE _ . Ils peuvent porter n'importe quelle extension; l'extension .bundle est recommandé par Apple, mais la plupart des logiciels portés utilisent .so par souci de compatibilité. En règle générale, vous utiliserez des 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 -bundle drapeau au compilateur.

Les dylibs et les bundles peuvent être chargés dynamiquement à l'aide des API dl (par exemple, dlopen, dlclose). Il n'est pas possible d'établir une liaison avec des ensembles comme s'il s'agissait de bibliothèques partagées. Cependant, il est possible qu'un paquet soit lié à de vraies bibliothèques partagées; ceux-ci seront chargés automatiquement lorsque le paquet est chargé.

Historiquement, les différences étaient plus significatives. Sous Mac OS X 10.0, il n’existait aucun moyen de charger dynamiquement des bibliothèques. Un ensemble d'API dyld (par exemple, NSCreateObjectFileImageFromFile, NSLinkModule) ont été introduits avec 10.1 pour charger et décharger des ensembles, mais ils ne fonctionnaient pas pour dylibs. Une bibliothèque de compatibilité dlopen fonctionnant avec des bundles a été ajoutée dans 10.3; dans 10.4, dlopen a été réécrit pour devenir une partie native de dyld et un support supplémentaire pour le chargement (mais pas le déchargement) des dylibs. Enfin, 10.5 a ajouté la prise en charge de l’utilisation de dlclose avec dylibs et a rendu obsolète les API 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 un chargement dynamique.

Enfin, sachez que sous Mac OS X, "bundle" peut aussi faire référence à des répertoires avec une structure normalisée contenant le code exécutable et les ressources utilisées par ce code. Il existe un certain chevauchement conceptuel (en particulier avec les "ensembles chargeables" tels que les plugins, qui contiennent généralement du code exécutable sous la forme d'un ensemble Mach-O), mais ils ne doivent pas être confondus avec les ensembles Mach-O décrits ci-dessus.

Références supplémentaires:

174
Miles

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

Il se trouve que c'est un problème commun.

Vérifiez la ligne 3b à page ArnaudRecipes sharedlib

Fondamentalement, .dylib est l'extension de fichier mac utilisée pour indiquer une bibliothèque partagée.

19
Martin York

La différence entre .dylib et .so sur mac os x réside dans la manière dont ils sont compilés. Pour les fichiers .so, vous utilisez -shared et pour .dylib, vous utilisez -dynamiclib. Les fichiers .so et .dylib sont interchangeables en tant que fichiers de bibliothèque dynamiques et ont le même type que DYLIB ou BUNDLE. Voici la lecture pour différents fichiers montrant cela.

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

La raison pour laquelle les deux sont équivalents sous Mac OS X est la compatibilité avec les versions antérieures pour les autres programmes UNIX OS compilés 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 correct dans la bibliothèque dynamique lors de l'étape de liaison. Pour ce faire, vous 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 ce message: Folie de la bibliothèque dynamique de Mac (peut-être Fortran uniquement) .

11
Zachary Kraus

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 des fichiers . so

tandis que

cmake ... -DBUILD_SHARED_LIBS=ON ...

crée . dynlib fichiers.

Peut-être que cela aide quelqu'un.

3
user2996950