GCC ABI兼容性

32

据我所知,使用不同版本的GCC应用二进制接口(ABI)的库是无法链接的。每个GCC版本都有ABI更改吗?如果我使用GCC 4.3.2,是否可以链接使用4.3.1构建的库?是否有一种矩阵列出了所有组合GCC版本的方式?


3个回答

22
自gcc-3.4.0以来,ABI具有向前兼容性。也就是说,使用旧版本制作的库可以与新版本链接,并且应该可以正常工作(反向则不行)。显然可能存在错误,但文档中只提到了一个错误:http://gcc.gnu.org/bugzilla/show_bug.cgi?id=33678

请问您能澄清第二句话吗?如果我的共享 DLL 是旧版本,但可执行文件是新版本,那就没问题;但如果我的共享 DLL 是新版本,而可执行文件是旧版本,那就不行了? - Cookie
@Cookie,没错。请注意这是针对编译器的规则,标准库有自己的规则,但它们也尽力保持向前兼容性。 - AProgrammer
6
看起来自 GCC 5.1 起它不再向前兼容。另请参见 因 abi::cxx11 造成的符号链接问题?GCC-5.1 的两个 C++ ABI 案例 - jww
1
我在使用GCC 5.2时遇到了同样的问题:我无法链接两个库:一个来自Ubuntu Wily软件包,另一个来自Intel Pin软件包(该软件包已使用旧版本的gcc进行编译)。 - Ta Thanh Dinh

16

1
哦,官方ABI页面上有一个代码示例(多ABI测试),其中使用了多个版本...如果他们接着说你应该重新编译所有内容以使用相同的版本,那么这是怎么可能的呢? - Fredrik Ullner
2
该示例展示了如何使用链接器以便能够链接多个库。但它们不会互操作:例如,您不能将一个向量从第一个库传递到另一个库。 - AProgrammer
1
也就是说,这是相对无意义的,因为显然这是你想要做的事情。 - Fredrik Ullner
@linuxbuild 如何使用?有任何示例吗? - John

4

啊,呀。
如何确定哪个gcc编译器编译了给定的二进制文件?以下是来自gcc-4.7.2-1-mingw32.README.txt 的警告:

二进制不兼容性通知!

GCC 4.7.0 中 C 和 C++ ABI 已更改,这意味着通常情况下您不能链接使用此版本编译器和 GCC 4.7.0 之前的版本编译的二进制文件。具体而言:

  • 默认情况下启用选项 -mms-bitfields,这意味着位域布局遵循 Microsoft 编译器的约定。

  • C++ 类成员函数现在遵循 __thiscall 调用约定。

  • 编译器现在假定调用方弹出堆栈以获取指向聚合返回值的隐式参数。这会影响按值返回结构体(例如复杂数学类型)的函数。


6
只是为了明确,我认为这只适用于在 Windows 上使用 GCC 的人。在 Linux 上,除了由于 4.7.0 和 4.7.1 中的一个错误而导致对 C++11 用户的兼容性破坏外,没有其他任何兼容性问题。即使如此,这个问题也在 4.7.2 中得到了修复,因此只需避免这两个问题版本,你就没问题了。 - John Zwinck

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