2015-10-19 134 views
0

我试图编译一个大的代码库编写的32位嵌入式处理器在64位桌面处理器上运行,以进行仿真/单元测试。我需要生成的对象成为共享库。这在Windows中不是问题,我可以像这样构建一个dll(/ DWIN32)并且运行良好。无法链接共享库与-mx32和gcc 4.7或gcc 4.8

在Linux中,我可以使用给予gcc和链接器的-m32选项进行编译和链接,并获得共享库。问题是,这个库(就像我用-m32指定的那样)是一个32位库,并且不会在我的64位版本库上运行。使用Python,我尝试加载库(使用ctypes.cdll.LoadLibrary())

OSError: out.so: wrong ELF class: ELFCLASS32 

我发现了-mx32选项,并根据docs这正是我想要的:

-mx32选项将int,long和指针类型设置为32位, 为x86-64体系结构生成代码。

所以,我通过-mx32到编译器和链接(更换我-m32选项),并得到以下(剪断输出):

/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.8/libstdc++.so when searching for -lstdc++ 
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.8/libstdc++.a when searching for -lstdc++ 
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.8/32/libstdc++.so when searching for -lstdc++ 
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.8/32/libstdc++.a when searching for -lstdc++ 
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.8/libstdc++.so when searching for -lstdc++ 
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.8/libstdc++.a when searching for -lstdc++ 
/usr/bin/ld: cannot find -lstdc++ 
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/libm.so when searching for -lm 
/usr/bin/ld: skipping incompatible /usr/lib/gcc/x86_64-linux-gnu/4.8/../../../x86_64-linux-gnu/libm.a when searching for -lm 
/usr/bin/ld: skipping incompatible /usr/lib/x86_64-linux-gnu/libm.so when searching for -lm 
/usr/bin/ld: skipping incompatible /usr/lib/x86_64-linux-gnu/libm.a when searching for -lm 
/usr/bin/ld: skipping incompatible /usr/lib/x86_64-linux-gnu/libm.so when searching for -lm 
/usr/bin/ld: skipping incompatible /usr/lib/x86_64-linux-gnu/libm.a when searching for -lm 
/usr/bin/ld: cannot find -lm 

我与GCC 4.7相同的结果和gcc 4.8。以上输出来自gcc 4.8。

我已经安装了gcc-4.8-multilib和g ++ - 4.8-multilib。

我的库路径是:

LIBRARY_PATH=/usr/lib/x86_64-linux-gnu:/usr/lib/gcc/x86_64-linux-gnu/4.8/32:/usr/lib/gcc/x86_64-linux-gnu/4.8/ 

从.bashrc中我看完之后这样的(如下图)指定,在绝望中加入/4.8/和/4.8/32/东西,链接器会只与工作的库绑定。

export LIBRARY_PATH=/usr/lib/$(gcc -print-multiarch):/usr/lib/gcc/x86_64-linux-gnu/4.8/32:/usr/lib/gcc/x86_64-linux-gnu/4.8/ 

正如我所说,这已经很好地在Windows上作为一个dll,我不得不相信我只是失去了一些东西。指针应该是32位,长整型应该是32位,整个事情应该在x86_64上运行。 -mx32表示它会做到这一点(对吧?)。

检查对象之一-m32编译后:

$:~/project$ file foo.o 
foo.o: ELF 32-bit LSB relocatable, Intel 80386, version 1 (SYSV), not stripped 

而且随着-mx32编译后检查相同的对象:

$:~/project$ file foo.o 
foo.o: ELF 32-bit LSB relocatable, x86-64, version 1 (SYSV), not stripped 

我要对这个错误的方式?我还可以使用我的32位共享库和某种兼容层吗?

我看到一个针对gcc 4.7的bug report关于这些链接错误......但我没有看到太多的结论。 This page说gcc 4.8是x32的推荐最小值,所以我安装了它。仍然 - 我无法把它链接起来。 -m32链接正常。

+0

假设您确实需要一个ELF 64位,它看起来像链接器无法找到由glibc提供的libm.so。你可以在库路径中加入'/ usr/lib64'吗? – alvits

+0

感谢您的回复@alvits,但我没有这个目录:'$ cd/usr/lib64 bash:cd:/ usr/lib64:没有这样的文件或目录' – skelliam

回答

1

-mx32选项不是你想要的。它编译代码为the x32 ABI,它使用带有64位寄存器和指令的32位地址。由此产生的代码与32位处理器(因为它使用64位指令)不兼容,但是与64位代码(将使用64位地址)不兼容。

使问题变得更加复杂,您在Windows上进行的测试一直没有按照您的想法进行。将/DWIN32传递给Visual C++编译器只定义了一个名为WIN32的宏(如-DWIN32对于GCC);它不会使编译器生成32位二进制文​​件。 64位Windows可执行文件不能加载32位库的;你一直在测试的库实际上是64位的。

如果要单元测试32位代码,则需要在完全32位系统上进行测试。 X32不是这样一个系统。

+0

Thanks @duskwuff。你能解释一下Visual Studio如何完成我想要的任务吗?是否有某种允许32位dll运行的抽象层? – skelliam

+0

它不;您在Windows上的测试方法存在缺陷。 '/ DWIN32'只是定义了一个名为“WIN32”的宏;它实际上并没有使Visual Studio构建32位代码。 – duskwuff

+0

任何为什么它会在Windows中编译和链接?我想真正的问题是为什么我不能与mx32链接?我会弄清楚之后会发生什么。或者,我应该采取的下一步方法是什么? @duskwuff – skelliam

0

您最初的错误,试图加载您成功构建的库,表明您没有使用32位版本的Python,因此无法构建32位共享库。

如果您安装了一个i386(32位)版本的Python,它应该能够加载该库。更重要的是,这是您需要在嵌入式i386目标上运行的Python版本。

请注意,以上所有假设您的“32位嵌入式处理器”是i386兼容的。如果不是(它是一个ARM或MIPS或其他一些32位嵌入式处理器),那么您需要为该目标安装交叉编译器来构建库和模拟器(例如QEMU)来运行可执行文件。

+0

最终目标是从64位版本的Matlab中加载它。我不需要完全模仿目标。我已经对eeprom读取等目标特定位进行了抽象。我可以在Windows中做我想做的事情。我以为我可以在Linux中构建相同的代码......听起来好像答案是,将其正确移植或忘记它。 – skelliam