旧版本的libc与我的二进制文件链接

时间:2012-10-04 18:44:40

标签: gcc libc

我继承了一个有一些问题的软件。我认为这些问题与静态链接的 libc 版本有关。

我在Windows XP机器上构建它,目标是x86 QNX Neutrino 6.3.2机器。

以前,使用 GCC 2.95.3 构建的软件(从技术上讲,它是包装并调用 GCC 的QNX的 QCC ) 有人添加了一个功能,并且必须将其移植到使用 GCC 3.3.5 进行构建,因为新功能需要它。

现在,该软件是我的。我需要做一些补充,但已注意到奇怪的行为。经过一番挖掘,我发现2.95.3和3.3.5的 libc 都有静态链接。根据{{​​3}},:

  

GCC 2.95.3(来自6.2.1或6.3)和GCC 3.3.5使用不同的C ++ ABI   并有不同的名称mangling。因此,您无法链接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台同事的电脑, libc.a 的3.3.5版本不存在。这个甚至是如何在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工程版本,从那以后一切都很好。

3 个答案:

答案 0 :(得分:0)

GCC 3.3是史前的,QNX是不是有更新的版本?

编译器或链接器应该有一些选项可以告诉它是详细的,您可以使用它来查看链接到的所有库路径和库。这可能会告诉你如何链接旧的lib。

答案 1 :(得分:0)

当我编译QNX 6.3.2时,我总是使用3.3.5与GNU C / C ++库。如果您没有指定GNU,默认情况下您将获得Dinkum库。我过去在Dinkum线程安全方面遇到了问题。试试这些标志:

qcc -V3.3.5,gcc_ntox86 -Y_gpp

-Y_gpp指示qcc使用GNU库。

答案 2 :(得分:0)

如果其他人遇到类似问题,据我所知,这里是我提出的四个问题的答案。他们并不鼓励。

1)您无法将其与不存在的libc.a文件链接。当然。

2)它选择2.95.3版本的libc.a,因为3.3.5版本不存在。

3)在与QNX人员的讨论中,他们表示对于QNX Neutrino 6.3.2,官方测试的编译器仅 2.95.3,即使GCC 3.3.5包含在已发布的Momentics版本,未经测试也未受支持。它碰巧就在那里。

4)选项:

a) Go to a newer version of QNX which uses a newer version of GCC
b) Get source for libc (and libm as it turns out) and build it with GCC 3.3.5.
   This one may pan out. Still waiting on QNX tech support.
c) Get already-built libraries from the QNX folks.
d) Don't use GCC 3.3.5 to build for Neutrino 6.3.2

此致
   卡尔

相关问题