osx上的.so和.dylib有什么区别?

时间:2010-02-26 05:31:21

标签: c++ c macos unix

.dylib是OSX上的动态库扩展,但是当我不能/不应该使用传统的unix .so共享对象时,我从来都不清楚。

我遇到的一些问题:

  • 在概念层面,.so和.dylib之间的主要区别是什么?
  • 什么时候可以/我应该使用哪一个?
  • 编译技巧&提示(例如,替换gcc -shared -fPIC,因为这不适用于osx)

4 个答案:

答案 0 :(得分:170)

Mac OS X用于可执行文件和库的Mach-O目标文件格式区分共享库动态加载的模块。使用otool -hv some_file查看some_file

的文件类型

Mach-O共享库的文件类型为 MH_DYLIB ,并带有扩展名.dylib。它们可以与通常的静态链接器标志链接,例如, libfoo.dylib的-lfoo。可以通过将-dynamiclib标志传递给编译器来创建它们。 (-fPIC是默认值,无需指定。)

可装载模块在Mach-O中被称为“捆绑”。他们的文件类型为 MH_BUNDLE 。他们可以进行任何延期; Apple建议使用扩展名.bundle,但为了兼容性,大多数移植软件都使用.so。通常,您将使用扩展应用程序的插件的软件包;在这种情况下,捆绑包将链接到应用程序二进制文件以获取对应用程序的导出API的访问权限。可以通过将-bundle标志传递给编译器来创建它们。

可以使用dl API(例如dlopendlclose)动态加载dylib和捆绑包。无法链接捆绑包,就像它们是共享库一样。但是,捆绑包可能与真实的共享库相关联;这些将在加载包时自动加载。

历史上,差异更为显着。在Mac OS X 10.0中,无法动态加载库。引入了一组dyld API(例如NSCreateObjectFileImageFromFileNSLinkModule)以及10.1加载和卸载包,但它们不适用于dylib。在10.3中添加了一个与bundle一起使用的dlopen兼容性库;在10.4中,dlopen被重写为dyld的原生部分,并添加了对加载(但不是卸载)dylib的支持。最后,10.5添加了对使用dlclose和dylibs的支持,并弃用了dyld API。

在像Linux这样的ELF系统上,both use the same file format;任何共享代码都可以用作库和动态加载。

最后,请注意,在Mac OS X中,"bundle" 也可以引用具有标准化结构的目录,该结构包含可执行代码和该代码使用的资源。存在一些概念上的重叠(特别是对于像插件这样的“可加载包”,它通常包含Mach-O包形式的可执行代码),但它们不应与上面讨论的Mach-O包混淆。

其他参考资料:

答案 1 :(得分:18)

文件.so不是共享库的UNIX文件扩展名。

恰好是一个普通的。

检查ArnaudRecipes sharedlib page

处的第3b行

基本上.dylib是用于表示共享库的mac文件扩展名。

答案 2 :(得分:9)

mac os x上.dylib和.so之间的区别在于它们是如何编译的。对于.so文件,您使用-shared和.dylib,您使用-dynamiclib。 .so和.dylib都可以作为动态库文件互换,并且类型为DYLIB或BUNDLE。下面是显示此信息的不同文件的读数。

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

两者在Mac OS X上等效的原因是为了向后兼容编译为.so文件类型的其他UNIX OS程序。

编译说明:无论是编译.so文件还是.dylib文件,都需要在链接步骤中将正确的路径插入动态库中。您可以通过添加-install_name和链接命令的文件路径来完成此操作。如果你不这样做,你将遇到这篇文章中的问题:Mac Dynamic Library Craziness (May be Fortran Only)

答案 3 :(得分:2)

我刚刚在使用cmake在OSX上构建天真代码时做了一个观察:

cmake ... -DBUILD_SHARED_LIBS = OFF ...

创建.so文件

cmake ... -DBUILD_SHARED_LIBS = ON ...

创建.dynlib文件。

也许这对任何人都有帮助。