0

I have inherited a piece of software which is having some issues. I believe the issues are related to the version of libc that is being statically linked.

I am building this on a Windows XP machine, targeting an x86 QNX Neutrino 6.3.2 machine.

Previously, the software built with GCC 2.95.3 (Well, technically, it's QNX's QCC that wraps and calls GCC) Someone added a feature and had to port it to build with GCC 3.3.5 because the new feature needed it.

Now, the software is mine. I need to make some additions but have noticed weird behavior. After some digging, I found that there are static links to both libc for 2.95.3 and 3.3.5. According to QNX's web site, :

GCC 2.95.3 (from 6.2.1 or 6.3) and GCC 3.3.5 use different C++ ABIs and have different name mangling. As a result, you can't link C++ binaries (objects, executables, libraries) built with GCC 2.95.3 with binaries built with GCC 3.3.5.

This is a breaking ABI change, so I am obviously concerned. I wrote a small test for this

#include <stdio.h>

int main()
{
    FILE *stream_ptr = popen("fakename","r"); /// use libc
    return 0;
}

and built it with 3.3.5:

QCC -V3.3.5,gcc_ntox86 small.cpp -o small.out

then used strings to see what has been statically linked for this program

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)

As you can see, libc for GCC 2.95.3 has been statically linked.

My first question is: How can I make this link with a 3.3.5 version of libc?

My second question is: Why does it link with 2.95.3 in the first place?

What am I doing wrong/missing? Any suggestions are welcome.

(There's probably 60 other things in the project linking with 2.95.3 objects, and I need to fix them all, so implementing popen() and 59 of his closest friends myself isn't the best of ideas...)

Thanks,

Karl

UPDATE:

So I haven't figured out how to fix this yet, but a little bit of background for QNX 6.3.2 so folks who stumble upon this later don't have to figure this out the hard way:

You can use the verbose option for the linker ld --verbose and have it spit out everything it does. Note that I got the following output when I did that:

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

As one can see, the linker is attempting to open the 3.3.5 version of libc.a, but it's simply not there. I took a look at 3 other coworkers computers, and the 3.3.5 version of libc.a is not there. How this is even working across a breaking ABI change, I'm not sure, but I am suspicious that some of the wonkiness in this project has to do with this discrepancy.

While this answers my original questions,

1) You can't make it link with nonexistant libc.a files,

2) It picks the 2.95.3 version because the 3.3.5 version isn't there,

it brings up new questions:

3) Why doesn't QNX ship a 3.3.5 version of libc.a with this version of Momentics? (or if they do, where do they hide it because I missed it.)

4) Are there any viable workarounds? I was able to build everything but the two most important servers in the project without using libc, but until I get the last two fixed up, I'm still searching for a solution.

Update to the Update:

Working with the QNX folks, they built me an unsupported, untested engineering version of libc.a, libm.a and libsocket.a with GCC 3.3.5, and everything has been good since.

kmort
  • 2,848
  • 2
  • 32
  • 54

3 Answers3

0

GCC 3.3 is prehistoric, isn't there a newer version for QNX?

There should be some option for the compiler or linker which will tell it to be verbose, which you could use to see all the library paths and libraries being linked to. That might show you how an older lib is being linked to.

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521
  • Yes, there is a newer version (several actually), but with embedded systems, sometimes you can't make the jump to a newer version. With this project, we are certainly stuck at 3.3.5. I'll debug with verbosity. Thanks, Karl – kmort Oct 05 '12 at 12:10
0

When I compile for QNX 6.3.2, I always use 3.3.5 with the GNU C/C++ libraries. If you don't specify GNU, you will get Dinkum libraries by default. I have had problems in the past with Dinkum thread safety. Try these flags:

qcc -V3.3.5,gcc_ntox86 -Y_gpp

The -Y_gpp directs qcc to use the GNU libraries.

andrewsi
  • 10,807
  • 132
  • 35
  • 51
TomH
  • 1
0

In case someone else runs into a similar problem, to the best of my knowledge, here are the answers to the four questions I asked. They are not encouraging.

1) You can't make it link with nonexistent libc.a files. Of course.

2) It picks the 2.95.3 version of libc.a because the 3.3.5 version isn't there.

3) During discussions with the QNX folks, they stated that for QNX Neutrino 6.3.2, the official, tested compiler is only 2.95.3, even though GCC 3.3.5 is included in the shipped version of Momentics, it is not tested nor supported. It just happens to be there.

4) Options:

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

Sincerely,
Karl

kmort
  • 2,848
  • 2
  • 32
  • 54