【发布时间】:2015-07-19 22:37:11
【问题描述】:
我在使用 arm-linux-gnueabihf-g++(来自 Linaro 的 gcc 4.8 版)的交叉编译程序上使用 Eigen3。目标平台是来自 gumstix 的 duovero,使用 Poky 发行版 - ARMv7。当我使用 Eigen 代码运行程序时,我在 Eigen 对象上得到了非常奇怪的值(请参阅本文末尾的输出示例)。
我试过关闭矢量化,我玩过所有这些标志
-marm
-mcpu=cortex-a7
-mfpu=neon
-mfloat-abi=hard
但总是得到相同的行为。如果我在 duovero 上编译相同的代码,它可以正常工作(向量已正确初始化),但在我交叉编译时却不行。我什至从不同的主机(windows7 和 ubuntu 14.04)交叉编译。
知道为什么会这样吗?
这是我的简单程序(从 cmets 更新)
#include <iostream>
using namespace std;
#include <stdio.h>
#include <Eigen/Eigen>
#include <Eigen/Dense>
using namespace Eigen;
int main()
{
cout << "Hello World!" << endl;
int j =3;
cout << j << endl << endl; // ok
float k =4.2;
cout << k << endl << endl; // not ok
printf("%f\n\n", k ); // ok
Vector3d test1;
test1 << 1.2, 2.3, 3.4;
cout << test1 << endl << endl; // not ok
printf("%f\n\n", test1(0) ); // ok
Vector3d test2(1,2,3);
cout << test2 << endl; // not ok
cout << test2(1) << endl << endl; // not ok
printf("%f\n\n", test2(0) ); // ok
cout << 0.5f << endl; // not ok
printf("%f\n\n", 0.5f ); // ok
return 0;
}
这是我得到的输出(更新)
Hello World!
3
0
4.200000
-1.24694e-06
-1.24695e-06
-1.24695e-06
1.200000
-1.24692e-06
-1.24692e-06
-1.24693e-06
3.8852e+68
1.000000
0
0.500000
编辑 当我添加标志时:-mfloat-abi=soft 我得到这个错误
arm-linux-gnueabihf-g++ -c -mfloat-abi=soft -g -Wall -W -fPIE -IC:\tmp\testingEigen -I. -IC:\COSMOS\source\thirdparty\arm\eigen3 -IC:\Qt\5.4\mingw491_32\mkspecs\linux-arm-gnueabihf-g++ -o main.obj C:\tmp\testingEigen\main.cpp
arm-linux-gnueabihf-g++ -o testingEigen main.obj
c:/program files (x86)/linaro/gcc-linaro-arm-linux-gnueabihf-4.8-2014.01/bin/../lib/gcc/arm-linux-gnueabihf/4.8.3/../../../../arm-linux-gnueabihf/bin/ld.exe: error: testingEigen uses VFP register arguments, main.obj does not
makefile:79: recipe for target 'testingEigen' failed
c:/program files (x86)/linaro/gcc-linaro-arm-linux-gnueabihf-4.8-2014.01/bin/../lib/gcc/arm-linux-gnueabihf/4.8.3/../../../../arm-linux-gnueabihf/bin/ld.exe: failed to merge target specific data of file main.obj
更新: 我尝试了 Notlikethat 的建议。测试了库(例如 readelf -h /usr/lib/libstdc++.so.6.0.18),发现当前构建的绝对是软浮动 ABI。
当我静态链接时,我的代码运行良好(即使交叉编译器用于硬浮点,这是因为硬件实际上具有 FPU,即使图像配置为软 fp)。接下来我做的是找到一个能够做softfp的交叉编译器,当我添加标志时它也可以工作。我是从https://launchpad.net/linaro-toolchain-binaries/+milestone/2012.04 下载的。
我想我的下一步是为可以进行硬浮动的 duovero 编译一个 poky 图像。有人做过吗?
最终更新: 实际上,我刚刚使用这些说明为 duovero 编译了来自 yocto (poky 1.7) 的最新 poky 图像https://github.com/gumstix/yocto-manifest
并意识到此构建使用硬 fp。现在我的交叉编译器 (arm-linux-gnueabihf-g++) 和目标具有相同的浮点配置,我的 Eigen 代码和其他一切都运行良好!快乐的! :)
【问题讨论】:
-
这肯定闻起来像一个浮动 ABI 问题(我什至不排除在库代码中出现一些狡猾的“在 x86 上工作正常”) - 在“玩过这些标志”中,你的意思是说你已经明确尝试过
-mfloat-abi=soft?交叉编译器很可能配置有与本机不同的默认值,因此您不一定希望选项的 absence 意味着一致的行为。 -
当我添加 -mfloat-abi=soft 我得到这个错误:ld.exe: 错误: testingEigen 使用 VFP 寄存器参数,main.obj 没有(我编辑了原始问题并添加了我从编译器得到的完整输出)。此时我的交叉编译器似乎只配置为硬浮点。 Eigen 是否需要软浮点才能工作?
-
将
-mfloat-abi=soft添加到编译器标志之外的链接器标志。 -
嗯,像
cout << 0.5f << endl;这样简单的事情还是一样吗? -
@TurboJ,如果我只将 -mfloat-abi=soft 添加到链接器标志(而不是编译器标志),它可以编译,但如果我保留它作为编译器标志,我会遇到同样的问题提到了 VFP 寄存器参数。我开始认为问题在于交叉编译器仅适用于硬浮点。对于适用于 Windows 的带有 soft 或 softfp 的 ARM 交叉编译器有什么建议吗?
标签: gcc arm cross-compiling eigen eigen3