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

Desde Portar software Unix a Darwin y Mac OS X
hasta ¿Cuáles son las diferencias entre .so y .dylib en osx?

2.1 Bibliotecas compartidas vs. Módulos cargables
Una característica de Mach-O que pilla a mucha gente por sorpresa es la estricta distinción entre bibliotecas compartidas y módulos cargables dinámicamente. En los sistemas ELF ambos son lo mismo; cualquier trozo de código compartido puede ser utilizado como biblioteca y para la carga dinámica. Utilice otool -hv algún_fichero para ver el tipo de archivo de algún_fichero.
Las bibliotecas compartidas de Mach-O tienen el tipo de archivo MH_DYLIB y llevan la extensión .dylib. Se pueden enlazar con las banderas habituales del enlazador estático, por ejemplo -lfoo para libfoo.dylib. Sin embargo, no pueden cargarse como un módulo. (Nota al margen: Las bibliotecas compartidas pueden cargarse dinámicamente a través de una API. Sin embargo, esa API es diferente a la de los paquetes y la semántica la hace inútil para una emulación de dlopen(). Más notablemente, las bibliotecas compartidas no pueden ser descargadas.)
Los módulos cargables se llaman "bundles" en lenguaje Mach-O. Tienen el tipo de archivo MH_BUNDLE. Como ningún componente involucrado se preocupa por ello, pueden llevar cualquier extensión. La extensión .bundle es la recomendada por Apple, pero la mayoría del software portado utiliza .so por razones de compatibilidad. Los bundles pueden cargarse y descargarse dinámicamente a través de las APIs de dyld, y hay una envoltura que emula a dlopen() sobre esa API. No es posible enlazar con los paquetes como si fueran bibliotecas compartidas. Sin embargo, es posible que un bundle esté enlazado con bibliotecas compartidas reales; éstas se cargarán automáticamente cuando se cargue el bundle.