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


214

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

我有一些问题:

  • 从概念上讲,.so和.dylib之间的主要区别是什么?
  • 什么时候可以/应该在另一个上使用?
  • 编译技巧和窍门(例如,替换gcc -shared -fPIC,因为它在osx上不起作用)

Answers:


206

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

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

可加载模块在Mach-O中称为“捆绑”。它们具有文件类型MH_BUNDLE。他们可以携带任何扩展名;.bundleApple建议使用该扩展名,但是大多数移植软件都是.so出于兼容性考虑使用。通常情况下,你会使用捆绑插件扩展应用; 在这种情况下,捆绑软件将针对应用程序二进制文件进行链接,以访问应用程序的导出API。可以通过将-bundle标志传递给编译器来创建它们。

既dylibs和软件包可以使用动态加载dl的API(例如dlopendlclose)。无法像捆绑包一样共享捆绑包。但是,捆绑包可能会链接到实际的共享库。捆绑包加载后,这些将自动加载。

从历史上看,差异更大。在Mac OS X 10.0中,无法动态加载库。一组使dyld的API(例如NSCreateObjectFileImageFromFileNSLinkModule)与10.1加载和卸载捆绑推出,但他们没有工作dylibs。甲dlopen,随着10.3的溶液中加入束加工兼容性库; 在10.4中,dlopen被重写为dyld的本机部分,并增加了对加载(但不卸载)dylib的支持。最终,10.5添加了对dlclose与dylib一起使用的支持,并弃用了dyld API。

在Linux等ELF系统上,两者都使用相同的文件格式;任何共享代码段都可以用作库并用于动态加载。

最后,请注意,在Mac OS X中,“捆绑包”可以指具有标准化结构的目录,该目录包含可执行代码和该代码使用的资源。在概念上存在一些重叠(特别是与“可加载包”(如插件,通常包含Mach-O包形式的可执行代码)重叠),但是不应将它们与上述Mach-O包混淆。

其他参考:


1
感谢您的广泛评论:)我是否正确理解,如果我从另一个捆绑软件加载一个捆绑软件(即路径为app->捆绑软件A->捆绑软件B),那么捆绑软件B将看不到任何内容A中的符号?如果是的话,有什么办法可以解决这个问题吗?我刚刚打了,我想:stackoverflow.com/questions/4193539/...
米哈伊尔Edoshin

4
@noloader:-dynamiclib是一个GCC标志。它使编译器传递-dylib给ld。
英里

Mac OSX上ld的手册页的更新URL:manpages.info/macosx/ld.1.html
netpoetica 2014年

18

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

它恰好是常见的一种。

ArnaudRecipes sharedlib页面上检查3b行

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


9
@ninefingers。正确。但是,除非有非常明确的说明,否则某些工具将使用默认值。例如,当使用-l <lib>标志时,编译器将在该平台上使用特定于平台的共享libray扩展名(实际的标志在编译器中可能非常多)。
马丁·约克2010年

14

在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(仅适用于Fortran)


我该./configure如何生成.dylib文件而不是捆绑文件.so./configure --enable-shared不执行此任务。
阿德米亚'17

根据我的经验,由于配置文件使用的是标准的UNIX / Linux文件名,因此Mac上的大多数配置文件都会生成.so文件或静态库文件。
Zachary Kraus

4

这只是我在使用cmake在OSX上构建幼稚代码时所做的观察:

cmake ... -DBUILD_SHARED_LIBS=OFF ...

创建.so文件

cmake ... -DBUILD_SHARED_LIBS=ON ...

创建.dynlib文件。

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.