【发布时间】:2012-10-04 18:44:39
【问题描述】:
我继承了一个有一些问题的软件。我认为这些问题与静态链接的 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's web site,:
GCC 2.95.3(来自 6.2.1 或 6.3)和 GCC 3.3.5 使用不同的 C++ ABI 并有不同的名称修饰。结果,您无法链接 C++ 使用 GCC 2.95.3 构建的二进制文件(对象、可执行文件、库) 使用 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 来查看该程序静态链接的内容
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
正如你所见,链接器试图打开libc.a的3.3.5版本,但它根本不存在。我查看了其他 3 台同事的计算机,没有 3.3.5 版本的 libc.a。我不确定这在 ABI 的重大变化中是如何起作用的,但我怀疑这个项目中的某些问题与这种差异有关。
虽然这回答了我最初的问题,但
1) 你不能让它链接到不存在的 libc.a 文件,
2) 它选择 2.95.3 版本,因为 3.3.5 版本不存在,
它提出了新的问题:
3) 为什么 QNX 不提供 3.3.5 版本的 libc.a 和这个版本的 Momentics?(或者如果他们提供,他们在哪里隐藏它,因为我错过了它。)
4) 是否有任何可行的解决方法?我能够在不使用 libc 的情况下构建项目中除了两个最重要的服务器之外的所有内容,但在我修复最后两个之前,我仍在寻找解决方案。
更新到更新:
与 QNX 人员合作,他们使用 GCC 3.3.5 为我构建了一个不受支持、未经测试的 libc.a、libm.a 和 libsocket.a 工程版本,此后一切都很好。
【问题讨论】: