当交叉编译为ARM未初始化的特征向量(Eigen vectors not initialized w

2019-10-23 01:42发布

我使用的使用ARM-Linux的gnueabihf-G ++(gcc版本4.8从Linaro的)的横编译的程序Eigen3。 目标平台是用老板问起分布从gumstix一个duovero - ARMv7的。 当我和本征代码运行程序,我得到的本征对象(请参阅本文章最后输出的例子)真的很奇怪值。

我试着关掉量化,我打过所有这些标志

-marm 
-mcpu=cortex-a7
-mfpu=neon 
-mfloat-abi=hard 

但总是得到相同的行为。 如果我编译在duovero相同的代码它工作正常(矢量正确初始化),但不是当我交叉编译。 我甚至来自不同主机的交叉编译(的windows7和Ubuntu 14.04)。

任何想法,为什么发生这种情况?

这是我简单的程序(从评论更新)

#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 =软了,我得到这个错误

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。 有没有人这样做呢?

最后更新:我其实只是汇编了yocto最新狭小图像(狭小1.7)使用这些指令duovero https://github.com/gumstix/yocto-manifest

并意识到这个版本使用硬FP。 现在我的交叉编译器(ARM-Linux的gnueabihf-G ++)和目标具有相同的浮点配置和我的代码以征和其他一切工作完美! 快乐! :)

Answer 1:

这个问题似乎是,你有一个软浮动的libstdc ++(和朋友)在设备上。

考虑一个看似平淡无奇的功能类似std::ostream::operator<<(float) -当你与硬盘浮动工具链进行交叉编译,您生成的代码将通过浮到功能在FPU寄存器。 静态链接器知道够仔细检查,这符合它的链接对库(硬浮那些与交叉工具链本身捆绑)。 然后你把二进制和设备上运行它...

动态链接器,是不太聪明,只是要确保任何的libstdc ++发现提供程序要求的符号。 它发现的这适合该法案类似,足以版本之一,所以一切似乎都不错。 除了现在你有你的地方是代码浮传递参数给库函数在FPU寄存器中的情况,但库函数(即软浮动)期待他们的浮动参数的通用寄存器,所以他们发现未初始化的垃圾。

做的最好的事情是避免严重的顺序大致减少“对一个库链接,对另一运行”完全不匹配,为此,有3周合理的方案,:

  1. 静态链接,当你交叉编译。
  2. 把交叉工具链的硬浮库某处设备的文件系统,你交叉编译的程序可以找到他们(可能诉诸LD_LIBRARY_PATH) - 显然,你不能简单地取代现有的库或者你会得到的逆ABI不匹配您安装的程序的其余部分。
  3. 关闭设备的系统库复制到您的主机,这样你就可以在他们点的交联剂,而不是它的捆绑库,并与交叉编译--mfloat-abi=soft

我通常会建议选择3作为一般的情况下,无论如何努力浮确实有一定程度的性能优势,因此对于浮点密集的代码,因此它可能是值得的努力得到它的工作位。

需要注意的是虽然有些硬浮动(即“ARM-Linux的gnueabi HF - ”)交叉工具链还包括通过multilib的软浮点库,其他人(如那些Linaro的我用),要么不爱,或只允许他们代表古代的目标选项,您可能不希望特定组合。 如果你确实有一个合适multilib的工具链,这就是@ TurboJ在评论建议是有关-使用arm-linux-gnueabihf-gcc作为链接命令( arm-linux-gnueabihf-ld )与--mfloat-abi=soft指定要告诉它,如果它支持反对其图书馆的软浮动版本进行链接。



文章来源: Eigen vectors not initialized when cross-compiled for ARM