我正在研究需要在多个不同的嵌入式平台上运行的 C 和 C++ 程序,为此我有交叉编译器,因此我可以在我的 x86 桌面上进行构建。
我在某些功能上遇到了一个可怕的问题,例如“strtod()”。这是我的简单测试程序:
#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;
}
通常我会使用动态链接构建所有程序,以使二进制文件尽可能小。以上在 x86 和 Power PC 上运行良好。但是,在 Arm 系统(带有 Debian 的 BeagleBoard xM)上,strtod() 行为不当(程序总是输出“0.000000”)。
我尝试使用“-static”选项构建程序,这在 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!!]
我还在 BeagleBone Black 上进行了测试,它的分布略有不同。两个版本(静态和动态)在 BBB 上都运行良好。
在库中挖掘,我发现了以下版本号:
交叉编译器工具链:libc-2.9.so
BeagleBoard XM(不工作):libc-2.13.so
BeagleBone Black(有效!):libc-2.16.so
所以我的交叉编译器是针对旧版本的 glibc 构建的。我在几个地方读到 glibc 应该向后兼容。
我考虑过仅静态链接 libc,但根据 this question除非所有库都是静态链接的,否则这是个坏主意。
静态链接一切正常,但对系统有严格的限制,这意味着我需要使二进制文件尽可能小。
有什么想法会导致 strtod()(和类似函数)出现可怕的问题和/或为什么 glibc 2.13 不向后兼容?
编辑: 我没有提到“soname”(即顶级名称)在所有平台上都是相同的:“libc.so.6”根据我对文档的阅读,“soname”中 .so 之后的数字是主要版本并且仅在界面更改时更改 - 因此所有这些版本都应该兼容。出现在实际文件名中的 .so 之前的数字(如上所示,可通过符号链接(symbolic link)找到)是次要版本。请参阅:link
最佳答案
通常版本号反射(reflect)了兼容性。 .so
和下一个点之间出现的数字表示主要修订版,不保证与任何其他主要修订版兼容。
紧随其后的数字(只有在您点击符号链接(symbolic link)后才能看到)表示次要修订。这些可以互换使用,符号链接(symbolic link)就是用来做到这一点的。该程序链接到 libc.so.6
或其他任何内容,并且在实际文件系统上,libc.so.6
是指向(例如)libc 的符号链接(symbolic link).so.6.12
.
glibc 试图在主要修订版之间保持兼容性,但有时他们只需要接受重大更改。通常,这是在发布新版本的 C 或 POSIX 标准并且以破坏二进制兼容性的方式更新函数签名时发生的。
任何出现在.so
之前的数字如果改变也会破坏兼容性;这些通常代表对程序的完全重写。例如 glib
与 glib2
。与 libc 无关。
ldd
工具对于调查库依赖关系和发现实际加载库的准确版本非常有用。
关于c++ - strtod() 的可怕错误 : glibc-2. 13 不向后兼容 glibc-2.9?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27221745/