当交叉编译为ARM未初始化的特征向量 [英] Eigen vectors not initialized when cross-compiled for ARM

查看:1102
本文介绍了当交叉编译为ARM未初始化的特征向量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm using Eigen3 on a cross compiled program using the arm-linux-gnueabihf-g++ (gcc version 4.8 from Linaro). The target platform is a duovero from gumstix using the Poky distribution - ARMv7. When I run the program with the Eigen code I get really strange values on the Eigen objects (see the output example at the end of this post).

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

I've tried to turn off vectorization, I've played with all these flags

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

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

but always get the same behavior. If I compile the same code on the duovero it works ok (vectors are properly initialized) but not when I cross-compile. I've even cross-compiled from different hosts (windows7 and ubuntu 14.04).

任何想法,为什么会这样?

Any idea why this is happening?

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

This is my simple program (updated from comments)

#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;
}

这是输出我得到(更新)

This is the output I get (updated)

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

Edit When I add the flag: -mfloat-abi=soft I get this error

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。

update: I tried what Notlikethat suggested. Tested the libraries (ex. readelf -h /usr/lib/libstdc++.so.6.0.18) and found that the current built is definitively soft-float ABI.

当我静态链接在我的code效果很好(即使交叉编译器是硬浮动,这个工程因为硬件实际上有一个FPU即使图像被配置为软FP)。我做的下一件事是找到一个交叉编译器,能够做到做softfp,它也工作时,我添加了标记。我下载了它从 https://launchpad.net/linaro-toolchain-binaries/+milestone /2012.04

When I link statically my the code works well (even if cross compiler is for hard float, this works because the hardware actually has an FPU even if the image is configured for soft fp). The next thing I did was to find a cross compiler that is able to do do softfp, and it also worked when I added the flag. I downloaded it from https://launchpad.net/linaro-toolchain-binaries/+milestone/2012.04.

我想我的下一个步骤是编译一个狭小图像,可以做硬浮动的duovero。有没有人这样做呢?

I guess my next step is to compile a poky image for the duovero that can do hard float. Has anyone done this?

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

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

and realised that this build uses hard fp. Now my cross compiler (arm-linux-gnueabihf-g++) and the target have the same floating point configuration and my code with Eigen and everything else is working perfectly! Happy! :)

推荐答案

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

The problem would seem to be that you have a soft-float libstdc++ (and friends) on the device.

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

Consider an innocuous-looking function like std::ostream::operator<<(float) - when you cross-compile with the hard-float toolchain, you generate code which will pass the float to the function in an FPU register. The static linker knows enough to double-check that this matches the libraries it's linking against (the hard-float ones bundled with the cross-toolchain itself). Then you take that binary and run it on the device...

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

The dynamic linker, being less clever, is just going to make sure that whatever libstdc++ it finds provides the symbols the program is asking for. It finds one of a similar-enough version which fits that bill, so all seems good. Except now you've got the situation where your code is passing float arguments to library functions in FPU registers, but the library functions (being soft-float) are expecting their float arguments in general-purpose registers, so they find uninitialised junk.

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

The best thing to do is to avoid the "link against one library, run against another" mismatch entirely, for which there are 3 reasonable options, in roughly decreasing order of severity:


  1. 静态链接时,交叉编译。

  2. 把交叉工具链的硬浮库某处设备的文件系统,你的交叉编译的程序可以找到它们(可能诉诸LD_LIBRARY_PATH) - 很明显,你不能简单地取代现有的库或者你会得到反为您安装的程序的其余部分ABI不匹配。

  3. 关闭设备系统库复制到你的主机上,这样你就可以在他们,而不是它的捆绑库点交联剂,并用交叉编译 - mfloat-ABI =软

  1. Link statically when you cross-compile.
  2. Put the cross-toolchain's hard-float libraries somewhere on the device's filesystem where you cross-compiled programs can find them (possibly resorting to LD_LIBRARY_PATH) - obviously you can't simply replace the existing libraries or you'd get the inverse ABI mismatch for the rest of your installed programs.
  3. Copy the system libraries off the device onto your host machine, so you can point the cross-linker at them instead of its bundled libraries, and cross-compile with --mfloat-abi=soft.

我通常建议选择3作为一般情况下,然而硬浮确实有一定程度的性能益处因此对于浮点密集型code,所以它可能是值得的努力得到位它的工作。

I'd normally suggest option 3 as the general case, however hard-float does have somewhat of a performance benefit so for floating-point-intensive code, so it may well be worth the bit of effort to get it to work.

请注意,虽然有些硬浮动(即臂Linux的gnueabi HF - )交叉工具链还包括通过multilib的软浮点库,其他(如Linaro的那些我使用)要么不爱,或者只让他们为选择特定组合重新presenting古老的目标,你可能不希望。如果你的没有的有一个合适multilib的工具链,这就是@ TurboJ的在评论中建议是有关 - 用 ARM-Linux的gnueabihf-GCC 作为链接命令(的 ARM-Linux的gnueabihf-LD )使用 - mfloat-ABI =软指定会告诉它针对其图书馆的软浮动版本链接,如果它支持。

Note that whilst some hard-float (i.e. "arm-linux-gnueabihf-") cross-toolchains also include soft-float libraries via multilib, others (like the Linaro ones I use) either don't, or only enable them for specific combinations of options representing ancient targets, which you probably don't want. If you did have a suitable multilib toolchain, that's what @TurboJ's suggestion in the comments is about - using arm-linux-gnueabihf-gcc as the link command (not arm-linux-gnueabihf-ld) with --mfloat-abi=soft specified would tell it to link against the soft-float versions of its libraries if it supports that.

这篇关于当交叉编译为ARM未初始化的特征向量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆