¿Cuáles son las diferencias entre .so y .dylib en osx?

214

.dylib es la extensión de biblioteca dinámica en OSX, pero nunca me ha quedado claro cuando no puedo / no puedo usar un objeto compartido .so tradicional de Unix.

Algunas de las preguntas que tengo:

  • A nivel conceptual, ¿cuáles son las principales diferencias entre .so y .dylib?
  • ¿Cuándo puedo / debo usar uno sobre el otro?
  • Trucos y consejos de compilación (por ejemplo, el reemplazo de gcc -shared -fPIC, ya que eso no funciona en osx)
Trent Davies
fuente

Respuestas:

206

El formato de archivo de objeto Mach-O utilizado por Mac OS X para ejecutables y bibliotecas distingue entre bibliotecas compartidas y módulos cargados dinámicamente . Use otool -hv some_filepara ver el tipo de archivo de some_file.

Las bibliotecas compartidas de Mach-O tienen el tipo de archivo MH_DYLIBy llevan la extensión .dylib. Se pueden vincular con los indicadores de enlazador estático habituales, por ejemplo, -lfoopara libfoo.dylib. Se pueden crear pasando la -dynamiclibbandera al compilador. ( -fPICes el valor predeterminado y no necesita especificarse)

Los módulos cargables se denominan "paquetes" en Mach-O speak. Tienen el tipo de archivo MH_BUNDLE. Pueden llevar cualquier extensión; .bundleApple recomienda la extensión , pero la mayoría de los programas portados se utilizan .sopor razones de compatibilidad. Por lo general, usará paquetes para complementos que amplían una aplicación; en tales situaciones, el paquete se vinculará con el binario de la aplicación para obtener acceso a la API exportada de la aplicación. Se pueden crear pasando la -bundlebandera al compilador.

Tanto los dylibs como los paquetes se pueden cargar dinámicamente utilizando las dlAPI (por ejemplo dlopen, dlclose). No es posible vincular contra paquetes como si fueran bibliotecas compartidas. Sin embargo, es posible que un paquete esté vinculado a bibliotecas compartidas reales; esos se cargarán automáticamente cuando se cargue el paquete.

Históricamente, las diferencias fueron más significativas. En Mac OS X 10.0, no había forma de cargar bibliotecas dinámicamente. Se introdujo un conjunto de API dyld (por ejemplo NSCreateObjectFileImageFromFile, NSLinkModule) con 10.1 para cargar y descargar paquetes, pero no funcionaron para dylibs. Se dlopenagregó una biblioteca de compatibilidad que funcionaba con paquetes en 10.3; en 10.4, dlopense reescribió para ser una parte nativa de dyld y se agregó soporte para cargar (pero no descargar) dylibs. Finalmente, 10.5 agregó soporte para usar dlclosecon dylibs y desaprobó las API dyld.

En sistemas ELF como Linux, ambos usan el mismo formato de archivo ; cualquier pieza de código compartido se puede usar como biblioteca y para carga dinámica.

Finalmente, tenga en cuenta que en Mac OS X, "paquete" también puede referirse a directorios con una estructura estandarizada que contiene código ejecutable y los recursos utilizados por ese código. Existe cierta superposición conceptual (particularmente con "paquetes cargables" como complementos, que generalmente contienen código ejecutable en forma de paquete Mach-O), pero no deben confundirse con los paquetes Mach-O discutidos anteriormente.

Referencias adicionales:

Millas
fuente
1
Gracias por este extenso comentario :) ¿Entiendo correctamente que si cargo un paquete de otro paquete (es decir, la ruta es aplicación -> paquete A -> paquete B), entonces el paquete B no podrá ver ninguno símbolos en el paquete A? Y si es así, ¿hay alguna forma de resolver esto de alguna manera? Acabo de acertar, creo: stackoverflow.com/questions/4193539/…
Mikhail Edoshin el
44
@noloader: -dynamiclibes una bandera de GCC. Hace que el compilador pase -dyliba ld.
Millas
URL actualizada para la página de manual para ld en Mac OSX: manpages.info/macosx/ld.1.html
netpoetica
18

El archivo .so no es una extensión de archivo UNIX para la biblioteca compartida.

Simplemente resulta ser común.

Verifique la línea 3b en la página sharedlib de ArnaudRecipes

Básicamente .dylib es la extensión de archivo mac utilizada para indicar una biblioteca compartida.

Martin York
fuente
99
@ninefingers. Correcto. Pero algunas de las herramientas usarán valores predeterminados a menos que algo sea muy explícito. por ejemplo, los compiladores usarán la extensión de libray compartida específica de la plataforma cuando se usa el indicador -l <lib> (el indicador real puede muy a través de los compiladores).
Martin York
14

La diferencia entre .dylib y .so en mac os x es cómo se compilan. Para los archivos .so que usa -shared y para .dylib usa -dynamiclib. Tanto .so como .dylib son intercambiables como archivos de biblioteca dinámica y tienen un tipo como DYLIB o BUNDLE. Aquí está la lectura de diferentes archivos que muestran esto.

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 razón por la que los dos son equivalentes en Mac OS X es la compatibilidad con versiones anteriores de otros programas del sistema operativo UNIX que se compilan con el tipo de archivo .so.

Notas de compilación: si compila un archivo .so o un archivo .dylib necesita insertar la ruta correcta en la biblioteca dinámica durante el paso de vinculación. Para ello, agregue -install_name y la ruta del archivo al comando de enlace. Si no hace esto, se encontrará con el problema que se ve en esta publicación: Mac Dynamic Library Craziness (puede ser solo Fortran) .

Zachary Kraus
fuente
¿Cómo puedo hacer ./configurepara generar .dylibarchivos en lugar de agrupar archivos .so? ./configure --enable-sharedno hace esta tarea
Admia
desde mi experiencia, la mayoría de los archivos de configuración en mac crearán un archivo .so o un archivo de biblioteca estática porque los archivos de configuración están usando nombres de archivo estándar de Unix / Linux.
Zachary Kraus
4

Solo una observación que acabo de hacer al construir código ingenuo en OSX con cmake:

cmake ... -DBUILD_SHARED_LIBS=OFF ...

crea archivos .so

mientras

cmake ... -DBUILD_SHARED_LIBS=ON ...

crea archivos .dynlib .

Quizás esto ayude a cualquiera.

usuario2996950
fuente