我可以为所有Linux编译器使用一个Linux .so文件吗?

4
我们需要将一个闭源C库集成到我们的项目中。另一方可以以任何我们需要的模式编译库,但我们支持许多不同的Windows和Linux编译器。
我知道DLL将与所有主要的Windows编译器兼容,因此我们可以只在Windows上使用一个库。但是我不熟悉Linux动态库(.so)。这些库是否以类似的方式在所有Linux环境下兼容?
谢谢

它是纯 C 库。(更新标签,虽然我们的项目是 C++) - Neil Kirk
“我知道一个DLL将兼容所有主要的Windows编译器,因此我们可以只使用一个库来适用于Windows。” - 先试一下。 我知道 - “使用不同编译器创建的对象文件和静态库,甚至使用同一编译器的显著不同版本创建的,通常无法链接在一起。(来源:http://www.mingw.org/wiki/MixingCompilers)” - SChepurin
@SChepurin "Dll's有些不同。有时候你可以将一个使用一种编译器构建的DLL链接到使用另一种编译器编译的应用程序中。" 我们可以做到这一点。 - Neil Kirk
2
根据经验,创建可在不同发行版和版本上运行的共享库和二进制文件需要相当惊人的努力。通常情况下,您最终会得到一个共享库,它需要在不同发行版之间不兼容的运行时库/版本/符号。如果您只使用libc,并在足够旧的发行版/glibc版本上创建共享库,则可能有机会。 - nos
你要找的词是ABI。所有的Windows编译器都有相同的ABI吗?我怀疑不是。所有的Linux编译器都有相同的ABI吗?当然不是。你需要做的是检查你计划支持的编译器(及其版本!)之间的ABI兼容性。 - Shahbaz
显示剩余2条评论
2个回答

2
您可能会遇到一些问题,涉及共享库libotherparty.so链接(和编译)的GNU libc版本。
您肯定需要知道libc的版本,并且可能需要请求第三方提供几个二进制库的变体。
我强烈建议阅读Drepper的论文:如何编写共享库。还可以查看这个问题和Levine的链接器和加载器书籍。
如果是C代码,则编译器并不重要。更重要的是ABI。还要了解符号版本控制
准备好遇到一些麻烦。 通过经验,您将了解到自由软件更可取。

你好,感谢您的回答。我是个 Linux 新手。关于第一句话,我可以让它们链接到任何必要的 GNU libc。为了获得最大兼容性,我应该告诉他们什么?关于第二句话,我需要哪些变种?我只想要 32 位 .so 和 64 位 .so 库,在任何 Linux 发行版上都可以使用 gcc。谢谢。 - Neil Kirk

1
如果预计函数接口会发生变化(C++公共/受保护类定义),库版本应该针对共享对象进行指定,包括更多或更少的函数,函数原型更改(返回数据类型(int、const int等)或参数列表更改)或数据类型更改(对象定义:类数据成员、继承、虚函数等)。
在创建共享对象库时可以指定库版本。如果预计将更新库,则应指定库版本。这对于动态链接的共享对象库尤其重要。这也避免了Microsoft“DLL hell”问题,其中系统升级更改标准库并破坏了期望旧版本共享对象函数的旧应用程序。
GNU C/C++库也会发生版本控制。这经常使使用GNU工具的一个版本编译的二进制文件与使用其他版本编译的二进制文件不兼容,除非这些版本也驻留在系统中。由于版本控制,同一库的多个版本可以驻留在同一系统上。库的版本包含在符号名称中,因此链接器知道应该链接哪个版本。
可以查看所使用的符号版本:nm csub1.o
默认情况下,在目标代码中未指定版本。

请看 链接库和目标文件布局

有一个GNU C/C++编译器标志专门处理符号版本。使用以下标志在编译时指定要使用的版本脚本:--version-script=your-version-script-file

注意:仅在创建共享库时才有用。假定程序员知道在静态链接时要链接哪些库。运行时链接可以为库不兼容提供机会。

还请参阅此处有关ABI兼容性的信息


这里描述了如何为向后兼容性版本化您自己的库,而不是与您在其上使用的发行版/工具链编译的库存在的问题。 - nos
@nos 是的,你说得对,但版本控制也要考虑在内。 - Jayesh Bhoi
该库将永远不会改变。 - Neil Kirk
2
@NeilKirk,著名的遗言。 - vonbrand
@vonbrand 这个库有一个函数,它的作用是解压经过专有格式压缩的数据。 - Neil Kirk

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接