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

.dylib è l’estensione della libreria dynamic su OSX, ma non mi è mai stato chiaro quando non posso / non dovrei usare un object condiviso .so tradizionale.

Alcune delle domande che ho:

  • A livello concettuale, quali sono le principali differenze tra .so e .dylib?
  • Quando posso / dovrei usarne uno sull’altro?
  • Trucchi e suggerimenti per la compilazione (ad esempio, la sostituzione di gcc -shared -fPIC, poiché non funziona su osx)

Il formato di file object Mach-O utilizzato da Mac OS X per file eseguibili e librerie distingue tra librerie condivise e moduli caricati dynamicmente . Usa otool -hv some_file per vedere il tipo di file di some_file .

Le librerie condivise Mach-O hanno il tipo di file MH_DYLIB e portano l’estensione .dylib. Possono essere collegati con i normali flag linker statici, ad es. -lfoo per libfoo.dylib. Possono essere creati passando il flag -dynamiclib 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 portare qualsiasi estensione; l’estensione .bundle è consigliata da Apple, ma la maggior parte dei software portati utilizza .so per motivi di compatibilità. In genere, utilizzerai i bundle per i plug-in che estendono un’applicazione; in tali situazioni, il bundle si collegherà al binario dell’applicazione per accedere all’API esportata dell’applicazione. Possono essere creati passando il flag -bundle al compilatore.

Sia i dylib che i bundle possono essere caricati dynamicmente usando le API dl (es. dlopen , dlclose ). Non è ansible collegarsi a bundle come se fossero librerie condivise. Tuttavia, è ansible che un bundle sia collegato a vere e proprie librerie condivise; quelli saranno caricati automaticamente quando il pacchetto è caricato.

Storicamente, le differenze erano più significative. In Mac OS X 10.0, non c’era modo di caricare dynamicmente le librerie. Un insieme di API dyld (es. NSCreateObjectFileImageFromFile , NSLinkModule ) sono stati introdotti con 10.1 per caricare e scaricare pacchetti, ma non hanno funzionato con dylibs. Una libreria di compatibilità dlopen che funzionava con i bundle è stata aggiunta in 10.3; in 10.4, dlopen stato riscritto come parte nativa di dyld e aggiunto supporto per il caricamento (ma non lo scarico) di dylibs. Infine, il 10,5 ha aggiunto il supporto per l’utilizzo di dlclose con dylibs e ha deprecato le API dyld.

Sui 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 codice eseguibile e le risorse utilizzate da quel codice. C’è una certa sovrapposizione concettuale (in particolare con “bundle caricabili” come i plugin, che generalmente contengono codice eseguibile sotto forma di un bundle Mach-O), ma non dovrebbero essere confusi con i bundle Mach-O discussi sopra.

Ulteriori riferimenti:

  • Fink Porting Guide , la base per questa risposta (anche se piuttosto datata, come è stata scritta per Mac OS X 10.3).
  • ld (1) e dlopen (3)
  • Argomenti di programmazione della libreria dynamic
  • Argomenti di programmazione Mach-O

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 usata per indicare una lib condivisa.

La differenza tra .dylib e .so su mac os x è come sono 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 per 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 è la compatibilità con gli altri programmi OS UNIX che vengono compilati con 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 dynamic durante la fase di collegamento. A tale scopo, aggiungi -install_name e il percorso del file al comando di collegamento. Se non lo fai, ti imbatterai nel problema riscontrato in questo post: Mac Dynamic Library Craziness (Può essere solo Fortran) .

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.