I'm working on C and C++ programs which need to run on several different embedded platforms, for which I have cross-complilers so I can do the build on my x86 desktop.
I have a horrible problem with certain functions, e.g. "strtod()". Here's my simple test program:
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv)
{
if ( (argc < 2) || (NULL == argv[1]) ) return 0;
double myDouble = strtod(argv[1], NULL);
printf("\nValue: %f\n\n", myDouble);
return 0;
}
Normally I build all programs with dynamic linking to keep the binaries as small as possible. The above works fine on the x86 and Power PC. However, on the Arm system (BeagleBoard xM with Debian) strtod() misbehaves (the program always outputs "0.000000").
I tried building the program with the option '-static', and that worked on the Beagle:
root@beaglexm:/app# ./test.dynamic 1.23 Value: 0.000000 [Dynamic linked version - WRONG!!] root@beaglexm:/app# ./test.static 1.23 Value: 1.230000 [Correct!!]
I also tested on a BeagleBone Black, which has a slightly different distribution. Both versions (static and dynamic) worked fine on the BBB.
Digging around in the libraries, I found the following version numbers:
Cross Compiler Toolchain: libc-2.9.so
BeagleBoard XM (DOESN'T WORK): libc-2.13.so
BeagleBone Black (WORKS!): libc-2.16.so
So my cross compiler is building against an older version of glibc. I've read in several places that glibc should be backwards-compatible.
I thought about static linking only libc, but according to this question it's a bad idea unless all libraries are statically linked.
Static linking everything does work, but there are serious constraints on the system which mean I need to keep the binaries as small as possible.
Any ideas what would cause horrible problems with strtod() (and similar functions) and/or why glibc 2.13 is not backwards compatible?
EDIT: I didn't mention that the "soname" (i.e. top level name) is the same on all platforms: "libc.so.6" From my reading of the docs, the number AFTER the .so in the "soname" is the major version and only changes if the interface changes - hence all these versions should be compatible. The number BEFORE the .so which appears in the actual file name (shown above, and found by following the symlink) is the minor version. See: link