.dylib是OSX上的动态库扩展,但是当我不能/不应该使用传统的unix .so共享对象时,我从来都不清楚。
我遇到的一些问题:
答案 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(例如dlopen
,dlclose
)动态加载dylib和捆绑包。无法链接捆绑包,就像它们是共享库一样。但是,捆绑包可能与真实的共享库相关联;这些将在加载包时自动加载。
历史上,差异更为显着。在Mac OS X 10.0中,无法动态加载库。引入了一组dyld API(例如NSCreateObjectFileImageFromFile
,NSLinkModule
)以及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)
答案 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文件。
也许这对任何人都有帮助。