C++ osx 上的 .so 和 .dylib 有什么区别?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2339679/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
What are the differences between .so and .dylib on osx?
提问by Trent Davies
.dylib is the dynamic library extension on OSX, but it's never been clear to me when I can't / shouldn't use a traditional unix .so shared object.
.dylib 是 OSX 上的动态库扩展,但是当我不能/不应该使用传统的 unix .so 共享对象时,我一直不清楚。
Some of the questions I have:
我的一些问题:
- At a conceptual level, what are the main differences between .so and .dylib?
- When can/should I use one over the other?
- Compilation tricks & tips (For example, the replacement for gcc -shared -fPIC, since that doesn't work on osx)
- 在概念层面上,.so 和 .dylib 之间的主要区别是什么?
- 我什么时候可以/应该使用一个?
- 编译技巧和技巧(例如,替换 gcc -shared -fPIC,因为它不适用于 osx)
采纳答案by Miles
The Mach-O object file format used by Mac OS X for executables and libraries distinguishes between shared librariesand dynamically loaded modules. Use otool -hv some_file
to see the filetype of some_file
.
Mac OS X 用于可执行文件和库的 Mach-O 目标文件格式区分共享库和动态加载的模块。用otool -hv some_file
看的文件类型some_file
。
Mach-O shared libraries have the file type MH_DYLIB
and carry the extension .dylib. They can be linked against with the usual static linker flags, e.g. -lfoo
for libfoo.dylib. They can be created by passing the -dynamiclib
flag to the compiler. (-fPIC
is the default and needn't be specified.)
Mach-O 共享库具有文件类型MH_DYLIB
并带有扩展名 .dylib。它们可以与通常的静态链接器标志链接,例如-lfoo
libfoo.dylib。它们可以通过将-dynamiclib
标志传递给编译器来创建。(-fPIC
是默认值,无需指定。)
Loadable modules are called "bundles" in Mach-O speak. They have the file type MH_BUNDLE
. They can carry any extension; the extension .bundle
is recommended by Apple, but most ported software uses .so
for the sake of compatibility. Typically, you'll use bundles for plug-insthat extend an application; in such situations, the bundle will link against the application binary to gain access to the application's exported API. They can be created by passing the -bundle
flag to the compiler.
可加载模块在 Mach-O 语言中被称为“包”。他们有文件类型MH_BUNDLE
。它们可以携带任何分机;该扩展.bundle
是 Apple 推荐的,但大多数移植软件.so
都是为了兼容性而使用的。通常,您将对扩展应用程序的插件使用捆绑包;在这种情况下,bundle 将链接到应用程序二进制文件以访问应用程序的导出 API。它们可以通过将-bundle
标志传递给编译器来创建。
Both dylibs and bundles can be dynamically loaded using the dl
APIs (e.g. dlopen
, dlclose
). It is not possible to link against bundles as if they were shared libraries. However, it is possible that a bundle is linked against real shared libraries; those will be loaded automatically when the bundle is loaded.
dylibs 和 bundles 都可以使用dl
API动态加载(例如dlopen
,dlclose
)。不可能像捆绑共享库一样链接捆绑包。但是,bundle 可能链接到真正的共享库;这些将在加载包时自动加载。
Historically, the differences were more significant. In Mac OS X 10.0, there was no way to dynamically load libraries. A set of dyld APIs (e.g. NSCreateObjectFileImageFromFile
, NSLinkModule
) were introduced with 10.1 to load and unload bundles, but they didn't work for dylibs. A dlopen
compatibility library that worked with bundles was added in 10.3; in 10.4, dlopen
was rewritten to be a native part of dyld and added support for loading (but not unloading) dylibs. Finally, 10.5 added support for using dlclose
with dylibs and deprecated the dyld APIs.
从历史上看,差异更为显着。在 Mac OS X 10.0 中,无法动态加载库。10.1 中引入了一组 dyld API(例如NSCreateObjectFileImageFromFile
, NSLinkModule
)来加载和卸载包,但它们不适用于 dylib。甲dlopen
,随着10.3的溶液中加入束加工兼容性库; 在 10.4 中,dlopen
被重写为 dyld 的本机部分,并添加了对加载(但不卸载)dylib 的支持。最后,10.5 添加了对dlclose
与 dylibs 一起使用的支持并弃用了 dyld API。
On ELF systems like Linux, both use the same file format; any piece of shared code can be used as a library and for dynamic loading.
在像 Linux 这样的 ELF 系统上,两者都使用相同的文件格式;任何一段共享代码都可以用作库和用于动态加载。
Finally, be aware that in Mac OS X, "bundle"can alsorefer to directories with a standardized structure that holds executable code and the resources used by that code. There is some conceptual overlap (particularly with "loadable bundles" like plugins, which generally contain executable code in the form of a Mach-O bundle), but they shouldn't be confused with Mach-O bundles discussed above.
最后,请注意,在 Mac OS X 中,“bundle”也可以指具有标准化结构的目录,其中包含可执行代码和该代码使用的资源。有一些概念上的重叠(特别是像插件这样的“可加载包”,它们通常包含 Mach-O 包形式的可执行代码),但它们不应与上面讨论的 Mach-O 包混淆。
Additional references:
补充参考:
- Fink Porting Guide, the basis for this answer (though pretty out of date, as it was written for Mac OS X 10.3).
- ld(1)and dlopen(3)
- Dynamic Library Programming Topics
- Mach-O Programming Topics
- Fink Porting Guide,这个答案的基础(虽然已经过时了,因为它是为 Mac OS X 10.3 编写的)。
- ld(1)和dlopen(3)
- 动态库编程主题
- Mach-O 编程主题
回答by Martin York
The file .so is not a UNIX file extension for shared library.
文件 .so 不是共享库的 UNIX 文件扩展名。
It just happens to be a common one.
它只是碰巧是一个常见的。
Check line 3b at ArnaudRecipes sharedlib page
检查ArnaudRecipes 共享库页面上的第3b 行
Basically .dylib is the mac file extension used to indicate a shared lib.
基本上 .dylib 是用于指示共享库的 mac 文件扩展名。
回答by Zachary Kraus
The difference between .dylib and .so on mac os x is how they are compiled. For .so files you use -shared and for .dylib you use -dynamiclib. Both .so and .dylib are interchangeable as dynamic library files and either have a type as DYLIB or BUNDLE. Heres the readout for different files showing this.
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
The reason the two are equivalent on Mac OS X is for backwards compatibility with other UNIX OS programs that compile to the .so file type.
两者在 Mac OS X 上等效的原因是为了与编译为 .so 文件类型的其他 UNIX OS 程序向后兼容。
Compilation notes: whether you compile a .so file or a .dylib file you need to insert the correct path into the dynamic library during the linking step. You do this by adding -install_name and the file path to the linking command. If you dont do this you will run into the problem seen in this post: Mac Dynamic Library Craziness (May be Fortran Only).
编译注意事项:无论编译.so文件还是.dylib文件,都需要在链接步骤中将正确的路径插入到动态库中。您可以通过将 -install_name 和文件路径添加到链接命令来完成此操作。如果你不这样做,你会遇到这篇文章中看到的问题:Mac Dynamic Library Craziness (May be Fortran Only)。
回答by user2996950
Just an observation I just made while building naive code on OSX with cmake:
只是我在使用 cmake 在 OSX 上构建原始代码时所做的观察:
cmake ... -DBUILD_SHARED_LIBS=OFF ...
creates .sofiles
创建.so文件
while
尽管
cmake ... -DBUILD_SHARED_LIBS=ON ...
creates .dynlibfiles.
创建.dynlib文件。
Perhaps this helps anyone.
也许这对任何人都有帮助。