.dylib是OSX上的动态库扩展,但是当我不能/不应该使用传统的unix .so共享库时,对我来说还不清楚。
我有一些问题:
- 从概念上讲,.so和.dylib之间的主要区别是什么?
- 什么时候可以/应该在另一个上使用?
- 编译技巧和窍门(例如,替换gcc -shared -fPIC,因为它在osx上不起作用)
.dylib是OSX上的动态库扩展,但是当我不能/不应该使用传统的unix .so共享库时,对我来说还不清楚。
我有一些问题:
Answers:
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。可以通过将-bundle
标志传递给编译器来创建它们。
既dylibs和软件包可以使用动态加载dl
的API(例如dlopen
,dlclose
)。无法像捆绑包一样共享捆绑包。但是,捆绑包可能会链接到实际的共享库。捆绑包加载后,这些将自动加载。
从历史上看,差异更大。在Mac OS X 10.0中,无法动态加载库。一组使dyld的API(例如NSCreateObjectFileImageFromFile
,NSLinkModule
)与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包混淆。
其他参考:
-dynamiclib
是一个GCC标志。它使编译器传递-dylib
给ld。
在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
不执行此任务。