在将代码打包为库时,我应该创建.a还是.so?

时间:2010-11-19 19:02:50

标签: c++ linker shared-libraries

我有一个软件库,我曾经创建.a文件,以便人们可以安装它们并链接它们:g++ foo.o -L/path/to -llibrary

但是现在我经常遇到只有.so文件可用的第三方库(而不是.a),而你只是在没有-l开关的情况下链接它们,例如g++ foo.o /path/to/liblibrary.so

这些解决方案有何区别?我是否更愿意为我的图书馆用户创建.so文件?

4 个答案:

答案 0 :(得分:9)

通常,libfoo.a是静态库,libfoo.so是共享库。您可以对静态或共享使用相同的-L / -l链接器选项。或者,您可以使用static或shared命名lib的完整路径。通常,库是静态的和共享的,以便为应用程序开发人员提供他们想要的选择。

静态库所需的所有代码都是最终可执行文件的一部分。这显然使它更大,但它也意味着它是独立的。编译完成后,您可以在不使用lib的情况下运行应用程序。

来自共享库的代码不是可执行文件的一部分。只有一些钩子可以使可执行文件知道它需要的lib的名称。为了运行您的应用程序,共享库必须存在于lib搜索路径中(例如$LD_LIBRARY_PATH)。

如果您有两个共享相同代码的应用程序,则每个应用程序都可以链接到共享库以保持二进制文件大小不变。如果你想升级应用程序的某些部分而不重建整个应用程序,那么共享库也很适合。

答案 1 :(得分:1)

的静态,共享动态和可加载库的概述

http://www.yolinux.com/TUTORIALS/LibraryArchives-StaticAndDynamic.html

答案 2 :(得分:1)

到目前为止,我已经看过的评论中没有真正提到的一些功能。

静态链接(.a / .lib)
在这些编译单元之间共享内存通常是可以的,因为它们应该(?将)使用相同的运行时。

静态链接意味着你避免'dll hell',但是重新编译成本是为了使用任何变化。如果最终可执行文件使用了多个这样的共享库,则静态链接到共享库(.so)会导致奇怪的结果 - 全局变量可能存在多次,使用哪一个以及初始化它们会导致完全不同地狱。

该库将成为已发布产品的一部分,但会进行模糊处理,无法直接使用。

共享/动态库(.so / .dll)
在这些编译单元之间共享内存可能是危险的,因为他们可能选择使用不同的运行时。这可能意味着您基于调试/发布或单/多线程或...

提供不同的共享/动态库

共享库(.so)不太容易'dll hell'然后动态库(.dll)因为它们包含非常特定的版本控制的选项。

针对.so进行编译将捕获文件内部的版本信息(难以伪造),以便您获得非常具体的.so用法。针对.lib / .dll进行编译只提供基本文件名,任何版本控制都由开发人员管理(使用命名或手动加载库并手动检查版本详细信息)

图书馆必须附带最终产品(其他人可以拿起并使用它)

答案 3 :(得分:0)

  

但是现在我经常遇到第三方库,其中只有.so文件可用[...]而你只是在没有-l开关的情况下链接它们,例如g ++ foo.o /path/to/liblibrary.so。

JFYI,如果您链​​接到没有SONAME集的共享库(与readelf -a liblibrary.so比较),您将最终将指定的liblibrary.so路径放入目标对象(可执行文件或其他共享库)因为用户对于放置程序及其相关文件的位置有自己的想法,所以这通常是不受欢迎的。首选方法是使用-L / path / to -llibrary,可能与-Wl,-rpath,/ whatever / path /一起使用,如果这是最终路径(例如,这些路径决策由Linux发行版决定)。 / p>

  

我是否更愿意为我的图书馆用户创建.so文件?

如果您分发源代码,用户将做出特定选择。