我继承了一个有一些问题的软件。我相信这些问题与静态链接的libc版本有关。
我在 Windows XP 机器上构建它,目标是 x86 QNX Neutrino 6.3.2 机器。
以前,使用GCC 2.95.3构建的软件 (嗯,从技术上讲,它是 QNX 的QCC包装并调用GCC)有人添加了一个功能,并且必须将其移植到使用GCC 3.3.5构建,因为新功能需要它。
现在,这个软件是我的。我需要做一些补充,但注意到奇怪的行为。经过一番挖掘,我发现2.95.3 和 3.3.5的libc都有静态链接。根据QNX 的网站,:
GCC 2.95.3(来自 6.2.1 或 6.3)和 GCC 3.3.5 使用不同的 C++ ABI 并具有不同的名称修饰。因此,您无法将使用 GCC 2.95.3 构建的 C++ 二进制文件(对象、可执行文件、库)与使用 GCC 3.3.5 构建的二进制文件链接起来。
这是一个重大的 ABI 更改,所以我显然很担心。我为此写了一个小测试
#include <stdio.h>
int main()
{
FILE *stream_ptr = popen("fakename","r"); /// use libc
return 0;
}
并用 3.3.5 构建它:
QCC -V3.3.5,gcc_ntox86 small.cpp -o small.out
然后使用字符串来查看该程序静态链接的内容
strings -a small.out | grep GCC
GCC: (GNU) 3.3.5 (qnx-nto)
GCC: (GNU) 3.3.5 (qnx-nto)
GCC: (GNU) 2.95.3
GCC: (GNU) 3.3.5 (qnx-nto)
如您所见,GCC 2.95.3 的 libc 已被静态链接。
我的第一个问题是:如何使用 3.3.5 版本的 libc 建立此链接?
我的第二个问题是:为什么它首先与 2.95.3 链接?
我在做什么错/错过了什么?欢迎任何建议。
(项目中可能还有 60 个其他东西与 2.95.3 对象相关联,我需要将它们全部修复,因此我自己实现popen()和他最亲密的 59 个朋友并不是最好的主意......)
谢谢,
卡尔
更新:
所以我还没有想出如何解决这个问题,但是有一点关于 QNX 6.3.2 的背景知识,所以后来偶然发现这个问题的人不必费力地解决这个问题:
您可以对链接器ld --verbose使用详细选项并让它吐出它所做的一切。请注意,当我这样做时,我得到了以下输出:
attempt to open C:/QNX632/host/win32/x86/usr/lib/gcc-lib/i386-pc-nto-qnx6.3.0/3.3.5//libc.a failed
attempt to open C:/QNX632/target/qnx6/x86/lib/gcc/3.3.5/libc.a failed
attempt to open C:/QNX632/target/qnx6/usr/i386-pc-nto-qnx6.3.0/lib//libc.a failed
attempt to open C:/QNX632/target/qnx6/usr/lib/libc.a failed
attempt to open C:/QNX632/target/qnx6/x86/lib//libc.a succeeded
可以看到,链接器正试图打开 3.3.5 版本的libc.a,但它根本不存在。我查看了其他 3 台同事的计算机,没有 3.3.5 版本的libc.a。我不确定这甚至是如何在突破性的 ABI 更改中起作用的,但我怀疑这个项目中的一些不稳定与这种差异有关。
虽然这回答了我最初的问题,
1)你不能让它与不存在的 libc.a 文件链接,
2) 它选择 2.95.3 版本,因为 3.3.5 版本不存在,
它提出了新的问题:
3) QNX 为什么不随这个版本的 Momentics 发布 3.3.5 版本的 libc.a?(或者如果他们这样做,他们把它藏在哪里,因为我错过了。)
4)是否有任何可行的解决方法?我能够在不使用 libc 的情况下构建项目中除了两个最重要的服务器之外的所有内容,但是在我修复最后两个服务器之前,我仍在寻找解决方案。
更新更新:
他们与 QNX 人员一起使用 GCC 3.3.5 为我构建了一个不受支持、未经测试的 libc.a、libm.a 和 libsocket.a 工程版本,此后一切都很好。