Was sind die Unterschiede zwischen .so und .dylib auf osx?

214

.dylib ist die dynamische Bibliothekserweiterung unter OSX, aber mir war nie klar, wann ich ein traditionelles, gemeinsam genutztes Unix-Objekt nicht verwenden kann / sollte.

Einige der Fragen, die ich habe:

  • Was sind auf konzeptioneller Ebene die Hauptunterschiede zwischen .so und .dylib?
  • Wann kann / soll ich eins über das andere verwenden?
  • Kompilierungstricks & Tipps (Zum Beispiel der Ersatz für gcc -shared -fPIC, da dies unter osx nicht funktioniert)
Trent Davies
quelle

Antworten:

206

Das von Mac OS X für ausführbare Dateien und Bibliotheken verwendete Mach-O-Objektdateiformat unterscheidet zwischen gemeinsam genutzten Bibliotheken und dynamisch geladenen Modulen . Verwenden otool -hv some_fileSie diese Option, um den Dateityp von anzuzeigen some_file.

Gemeinsame Mach-O-Bibliotheken haben den Dateityp MH_DYLIBund tragen die Erweiterung .dylib. Sie können mit den üblichen statischen Linker-Flags verknüpft werden, z -lfoo. B. für libfoo.dylib. Sie können erstellt werden, indem das -dynamiclibFlag an den Compiler übergeben wird. ( -fPICist die Standardeinstellung und muss nicht angegeben werden.)

Ladefähige Module werden in Mach-O-Sprache als "Bundles" bezeichnet. Sie haben den Dateityp MH_BUNDLE. Sie können jede Verlängerung tragen; Die Erweiterung .bundlewird von Apple empfohlen, die meisten portierten Programme werden jedoch .soaus Kompatibilitätsgründen verwendet. In der Regel verwenden Sie Bundles für Plug-Ins , die eine Anwendung erweitern. In solchen Situationen wird das Bundle mit der Anwendungsbinärdatei verknüpft, um Zugriff auf die exportierte API der Anwendung zu erhalten. Sie können erstellt werden, indem das -bundleFlag an den Compiler übergeben wird.

Beide dylibs und Bündel können dynamisch die Verwendung geladen werden dlAPIs (z dlopen, dlclose). Es ist nicht möglich, eine Verknüpfung mit Bundles herzustellen, als wären sie gemeinsam genutzte Bibliotheken. Es ist jedoch möglich, dass ein Bundle mit echten gemeinsam genutzten Bibliotheken verknüpft ist. Diese werden automatisch geladen, wenn das Bundle geladen wird.

Historisch gesehen waren die Unterschiede signifikanter. In Mac OS X 10.0 gab es keine Möglichkeit, Bibliotheken dynamisch zu laden. Ein Satz von APIs dyld (z NSCreateObjectFileImageFromFile, NSLinkModule) wurde mit 10.1 zum Laden und Entladen Bündel eingeführt, aber sie haben nicht die Arbeit für dylibs. Eine dlopenKompatibilitätsbibliothek, die mit Bundles funktioniert, wurde in 10.3 hinzugefügt. in 10.4 dlopenwurde umgeschrieben, um ein nativer Teil von dyld zu sein, und Unterstützung für das Laden (aber nicht das Entladen) von Dylibs hinzugefügt. Schließlich fügte 10.5 Unterstützung für die Verwendung dlclosemit Dylibs hinzu und veraltete die dyld-APIs.

Auf ELF-Systemen wie Linux verwenden beide dasselbe Dateiformat . Jeder gemeinsam genutzte Code kann als Bibliothek und zum dynamischen Laden verwendet werden.

Beachten Sie schließlich, dass "Bundle" in Mac OS X auch auf Verzeichnisse mit einer standardisierten Struktur verweisen kann , die ausführbaren Code und die von diesem Code verwendeten Ressourcen enthält. Es gibt einige konzeptionelle Überschneidungen (insbesondere bei "ladbaren Bundles" wie Plugins, die im Allgemeinen ausführbaren Code in Form eines Mach-O-Bundles enthalten), sie sollten jedoch nicht mit den oben diskutierten Mach-O-Bundles verwechselt werden.

Zusätzliche Referenzen:

Meilen
quelle
1
Vielen Dank für diesen ausführlichen Kommentar :) Verstehe ich es richtig, dass Bundle B keine sehen kann, wenn ich ein Bundle aus einem anderen Bundle lade (dh der Pfad lautet app -> Bundle A -> Bundle B) Symbole in Bündel A? Und wenn ja, gibt es Möglichkeiten, dies irgendwie zu lösen? Ich habe es gerade getroffen, denke ich: stackoverflow.com/questions/4193539/…
Mikhail Edoshin
4
@noloader: -dynamiclibist eine GCC-Flagge. Dadurch wird der Compiler -dyliban ld übergeben.
Meilen
Aktualisiert URL für Manpage ld auf Mac OSX: manpages.info/macosx/ld.1.html
netpoetica
18

Die Datei .so ist keine UNIX-Dateierweiterung für die gemeinsam genutzte Bibliothek.

Es ist einfach eine häufige.

Überprüfen Sie Zeile 3b auf der ArnaudRecipes-Seite "sharedlib"

Grundsätzlich ist .dylib die Mac-Dateierweiterung, mit der eine gemeinsam genutzte Bibliothek angegeben wird.

Martin York
quelle
9
@ Neunfinger. Richtig. Einige der Tools verwenden jedoch Standardwerte, es sei denn, etwas ist sehr explizit. Beispiel: Compiler verwenden dort die plattformspezifische Shared Libray-Erweiterung, wenn das Flag -l <lib> verwendet wird (das tatsächliche Flag kann sich sehr über Compiler erstrecken).
Martin York
14

Der Unterschied zwischen .dylib und .so auf Mac OS X besteht darin, wie sie kompiliert werden. Für .so-Dateien verwenden Sie -shared und für .dylib -dynamiclib. Sowohl .so als auch .dylib sind als dynamische Bibliotheksdateien austauschbar und haben entweder den Typ DYLIB oder BUNDLE. Hier ist die Anzeige für verschiedene Dateien, die dies zeigen.

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

Der Grund, warum die beiden unter Mac OS X gleichwertig sind, liegt in der Abwärtskompatibilität mit anderen UNIX-Betriebssystemprogrammen, die mit dem Dateityp .so kompiliert werden.

Kompilierungshinweise: Unabhängig davon, ob Sie eine .so-Datei oder eine .dylib-Datei kompilieren, müssen Sie während des Verknüpfungsschritts den richtigen Pfad in die dynamische Bibliothek einfügen. Dazu fügen Sie -install_name und den Dateipfad zum Verknüpfungsbefehl hinzu. Wenn Sie dies nicht tun, werden Sie auf das in diesem Beitrag beschriebene Problem stoßen : Mac Dynamic Library Craziness (möglicherweise nur Fortran) .

Zachary Kraus
quelle
wie kann ich das machen ./configure , dass .dylibDateien generiert werden, anstatt Dateien zu bündeln .so? ./configure --enable-sharedmacht diese Aufgabe nicht.
Admia
Nach meiner Erfahrung erstellen die meisten Konfigurationsdateien auf dem Mac entweder eine .so-Datei oder eine statische Bibliotheksdatei, da die Konfigurationsdateien Standard-Unix- / Linux-Dateinamen verwenden.
Zachary Kraus
4

Nur eine Beobachtung, die ich gerade gemacht habe, als ich mit cmake naiven Code unter OSX erstellt habe:

cmake ... -DBUILD_SHARED_LIBS=OFF ...

erstellt .so- Dateien

während

cmake ... -DBUILD_SHARED_LIBS=ON ...

erstellt .dynlib Dateien.

Vielleicht hilft das jedem.

user2996950
quelle