unix 在macOS上,.so和.dylib有什么区别?

jpfvwuh4  于 2022-11-23  发布在  Unix
关注(0)|答案(4)|浏览(331)

.dylib是macOS上的动态库扩展,但我一直不清楚什么时候我不能/不应该使用传统的unix.so共享对象。
我有一些问题:

  • 在概念层面上,.so和.dylib之间的主要区别是什么?
  • 我何时可以/应该使用其中一种而不是另一种?
  • 编译技巧和提示(例如,gcc -shared -fPIC的替代,因为它在osx上不起作用)
6ojccjat

6ojccjat1#

Mac OS X用于可执行文件和库的Mach-O目标文件格式区分共享库动态加载的模块。使用otool -hv some_file可以查看some_file的文件类型。
Mach-O共享库的文件类型为**MH_DYLIB,扩展名为. dylib。它们可以通过常用的静态链接器标志进行链接,例如-lfoo表示libfoo. dylib。它们可以通过将-dynamiclib标志传递给编译器来创建。(-fPIC是默认值,不需要指定。)
在Mach-O语言中,可加载模块被称为“包”。它们的文件类型为
MH_BUNDLE**。它们可以携带任何扩展名;扩展名.bundle是Apple推荐的,但大多数移植软件出于兼容性考虑使用.so。在这种情况下,捆绑包将链接到应用程序二进制文件,以获得对应用程序导出API的访问权限。
dylib和bundle都可以使用dl API动态加载(例如dlopendlclose)。不可能将bundle链接为共享库。但是,可以将bundle链接为真实的的共享库;当加载捆绑包时,这些将被自动加载。
在Mac OS X 10.0中,没有动态加载库的方法。10.1中引入了一组dyld API(例如NSCreateObjectFileImageFromFileNSLinkModule)来加载和卸载bundle,但它们不适用于dylibs。10.3中增加了一个dlopen兼容库,可以与bundle一起使用;在10.4中,dlopen被重写为dyld的本机部分,并添加了对加载(但不卸载)dylib的支持。最后,10.5添加了对将dlclose与dylib一起使用的支持,并弃用了dyld API。
在ELF系统(如Linux)上,both use the same file format;任何一段共享代码都可以用作库并用于动态加载。
最后,请注意,在Mac OS X中,"bundle" * 也 * 可以指具有标准化结构的目录,其中包含可执行代码和代码所使用的资源。虽然存在一些概念上的重叠(特别是与“可加载包”,如插件,通常包含Mach-O包形式的可执行代码),但它们不应与上面讨论的Mach-O包混淆。
其他参考:

nqwrtyyt

nqwrtyyt2#

.dylib和.so在mac os x上的不同之处在于它们是如何编译的。对于.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动态库疯狂(可能仅限于Fortran)。

qco9c6ql

qco9c6ql3#

文件.so不是共享库的UNIX文件扩展名。
它只是碰巧是一个普通的。
检查ArnaudRecipes sharedlib page处的线路3b
基本上.dylib是mac文件扩展名,用于表示共享库。

hpcdzsge

hpcdzsge4#

这是我在OSX上使用cmake构建原始代码时的一个观察结果:

cmake ... -DBUILD_SHARED_LIBS=OFF ...

创建**.so**文件
同时

cmake ... -DBUILD_SHARED_LIBS=ON ...

创建**.dynlib**文件。
也许这对任何人都有帮助。

相关问题