Quali sono le differenze tra .so e .dylib su osx?


214

.dylib è l'estensione dinamica della libreria su OSX, ma non mi è mai stato chiaro quando non posso / non dovrei usare un oggetto condiviso .so unix tradizionale.

Alcune delle domande che ho:

  • A livello concettuale, quali sono le principali differenze tra .so e .dylib?
  • Quando posso / dovrei usare l'uno rispetto all'altro?
  • Suggerimenti e trucchi per la compilazione (ad esempio, la sostituzione di gcc -shared -fPIC, poiché non funziona su osx)

Risposte:


206

Il formato del file oggetto Mach-O utilizzato da Mac OS X per eseguibili e librerie distingue tra librerie condivise e moduli caricati dinamicamente . Utilizzare otool -hv some_fileper vedere il tipo di file di some_file.

Le librerie condivise di Mach-O hanno il tipo di file MH_DYLIBe portano l'estensione .dylib. Possono essere collegati con i normali flag di linker statici, ad esempio -lfooper libfoo.dylib. Possono essere creati passando la -dynamiclibbandiera al compilatore. ( -fPICè il valore predefinito e non è necessario specificarlo.)

I moduli caricabili sono chiamati "bundle" in Mach-O speak. Hanno il tipo di file MH_BUNDLE. Possono trasportare qualsiasi estensione; l'estensione .bundleè consigliata da Apple, ma la maggior parte dei software portati utilizza .soper motivi di compatibilità. In genere, utilizzerai i bundle per i plug-in che estendono un'applicazione; in tali situazioni, il bundle si collegherà al file binario dell'applicazione per ottenere l'accesso all'API esportata dell'applicazione. Possono essere creati passando la -bundlebandiera al compilatore.

Entrambi dylibs e fasci possono essere caricati dinamicamente utilizzando le dlAPI (ad esempio dlopen, dlclose). Non è possibile collegarsi a pacchetti come se fossero librerie condivise. Tuttavia, è possibile che un bundle sia collegato a librerie condivise reali; quelli verranno caricati automaticamente quando il pacchetto viene caricato.

Storicamente, le differenze erano più significative. In Mac OS X 10.0, non c'era modo di caricare dinamicamente le librerie. Un set di API dyld (ad es NSCreateObjectFileImageFromFile. NSLinkModule) Sono state introdotte con 10.1 per caricare e scaricare bundle, ma non hanno funzionato per i dylibs. Una dlopenlibreria di compatibilità che ha funzionato con i bundle è stata aggiunta in 10.3; in 10.4, è dlopenstato riscritto come parte nativa di dyld e ha aggiunto il supporto per il caricamento (ma non lo scaricamento) di dylibs. Infine, 10.5 ha aggiunto il supporto per l'utilizzo dlclosecon dylibs e ha deprecato le API dyld.

Su sistemi ELF come Linux, entrambi usano lo stesso formato di file ; qualsiasi parte di codice condiviso può essere utilizzata come libreria e per il caricamento dinamico.

Infine, tieni presente che in Mac OS X, "bundle" può anche fare riferimento a directory con una struttura standardizzata che contiene il codice eseguibile e le risorse utilizzate da quel codice. Vi è una sovrapposizione concettuale (in particolare con "bundle caricabili" come plug-in, che generalmente contengono codice eseguibile sotto forma di un bundle Mach-O), ma non dovrebbero essere confusi con i bundle Mach-O discussi sopra.

Riferimenti aggiuntivi:


1
Grazie per questo ampio commento :) Lo capisco correttamente, che se carico un pacchetto da un altro pacchetto (ovvero il percorso è app -> pacchetto A -> pacchetto B), allora il pacchetto B non sarà in grado di vedere alcun simboli nel gruppo A? E se sì, ci sono modi per risolverlo in qualche modo? Ho appena colpito, penso: stackoverflow.com/questions/4193539/...
Mikhail Edoshin

4
@noloader: -dynamiclibè un flag GCC. Fa passare il compilatore -dyliba ld.
Miglia

URL aggiornato per pagina man per ld su Mac OSX: manpages.info/macosx/ld.1.html
netpoetica

18

Il file .so non è un'estensione di file UNIX per la libreria condivisa.

Capita solo di essere comune.

Controlla la riga 3b nella pagina condivisa di ArnaudRecipes

Fondamentalmente .dylib è l'estensione del file mac utilizzata per indicare una lib condivisa.


9
@ninefingers. Corretta. Ma alcuni degli strumenti useranno i valori predefiniti a meno che qualcosa non sia molto esplicito. ad esempio, i compilatori useranno l'estensione libray condivisa specifica per la piattaforma quando viene utilizzato il flag -l <lib> (il flag effettivo può essere molto diffuso tra i compilatori).
Martin York,

14

La differenza tra .dylib e .so su mac os x è come vengono compilati. Per i file .so che usi -shared e per .dylib usi -dynamiclib. Sia .so che .dylib sono intercambiabili come file di libreria dinamici e hanno un tipo come DYLIB o BUNDLE. Ecco la lettura di diversi file che mostrano questo.

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

Il motivo per cui i due sono equivalenti su Mac OS X è per la retrocompatibilità con altri programmi del sistema operativo UNIX che vengono compilati per il tipo di file .so.

Note sulla compilazione: se si compila un file .so o un file .dylib è necessario inserire il percorso corretto nella libreria dinamica durante la fase di collegamento. Puoi farlo aggiungendo -install_name e il percorso del file al comando di collegamento. Se non lo fai, ti imbatterai nel problema visto in questo post: Mac Dynamic Library Craziness (può essere solo Fortran) .


come posso fare ./configureper generare .dylibfile piuttosto che raggruppare file .so? ./configure --enable-sharednon svolge questa attività.
Admia,

dalla mia esperienza, la maggior parte dei file di configurazione su Mac costruirà un file .so o un file di libreria statica perché i file di configurazione utilizzano nomi di file unix / linux standard.
Zachary Kraus,

4

Solo un'osservazione che ho appena fatto durante la creazione di codice ingenuo su OSX con cmake:

cmake ... -DBUILD_SHARED_LIBS=OFF ...

crea file .so

mentre

cmake ... -DBUILD_SHARED_LIBS=ON ...

crea file .dynlib .

Forse questo aiuta chiunque.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.