【发布时间】:2015-01-29 01:35:07
【问题描述】:
我正在开发需要在几个不同的嵌入式平台上运行的 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 系统(BeagleBoard xM with Debian)上,strtod() 行为异常(程序总是输出“0.000000”)。
我尝试使用选项“-static”构建程序,并且在 Beagle 上有效:
root@beaglexm:/app# ./test.dynamic 1.23 值:0.000000 [动态链接版本-错误!!] root@beaglexm:/app# ./test.static 1.23 价值:1.230000 [正确的!!]我还在 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 之前的数字(如上所示,可通过符号链接找到)是次要版本。见:link
【问题讨论】: