.dylib是macOS上的动态库扩展名,但我从来没有清楚地知道何时不能/不应该使用传统的unix .so共享对象。
我有一些问题:
- 在概念层面上,.so和.dylib之间的主要区别是什么?
- 何时可以/应该使用其中之一?
- 编译技巧和提示(例如,替代gcc -shared -fPIC的方法,因为在osx上无法使用)
历史上,两者之间的差异更为重大。在Mac OS X 10.0中,没有办法动态加载库。一组dyld API(例如NSCreateObjectFileImageFromFile
,NSLinkModule
)在10.1中被引入以加载和卸载捆绑包,但它们无法用于dylibs。在10.3中添加了一个能够与捆绑包配合使用的兼容性库;在10.4中,被重写为dyld的本地部分,并添加了对加载dylibs的支持(但不支持卸载)。最后,10.5增加了对使用dlclose
关闭dylibs的支持,并弃用了dyld API。
在像Linux这样的ELF系统上,两者使用相同的文件格式;任何共享代码均可用作库并进行动态加载。
最后,请注意,在Mac OS X中,“bundle”还可以指具有标准结构的目录,其中包含可执行代码及其使用的资源。存在一些概念上的重叠(特别是与“可加载捆绑包”(如插件)有关的内容,通常包含以Mach-O捆绑包形式的可执行代码),但不应与上述讨论的Mach-O捆绑包混淆。
其他参考资料:
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
./configure
生成 .dylib
文件而不是 .so
束文件? ./configure --enable-shared
无法完成此任务。 - Admia.so
文件,无论是在Mac还是Linux上构建的,都可以在Mac和Linux上使用? - KcFnMi在使用cmake在OSX上编写天真的代码时,我刚刚观察到了一个现象:
cmake ... -DBUILD_SHARED_LIBS=OFF ...
创建.so文件
而
cmake ... -DBUILD_SHARED_LIBS=ON ...
创建.dynlib文件。
也许这能帮助任何人。
./configure
时加上 --with-shared
。一个常用的库,比如 libncurses,在 Mac OS X 上默认情况下不会构建 .dynlib 文件,需要这个选项。 - hexalys
-dynamiclib
是 GCC 的一个标志。它会让编译器传递-dylib
给 ld。 - Miles