无法使用-mx32和gcc 4.7或gcc 4.8链接共享库

时间:2015-10-19 21:11:55

标签: linux gcc embedded 32bit-64bit x86-64

我正在尝试编译为32位嵌入式处理器编写的大型代码库,以便在64位桌面处理器上运行,以进行模拟/单元测试。我需要生成的对象是一个共享库。这不是Windows中的问题,我可以像这样构建一个dll(/ DWIN32)并运行正常。

在Linux中,我能够编译并链接给gcc和链接器的-m32选项并获取共享库。问题是,这个库(就像我用-m32指定的那样)是一个32位的库,不会在我的64位arch上运行。使用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位,long应为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链接正常。

2 个答案:

答案 0 :(得分:1)

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

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

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

答案 1 :(得分:0)

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

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

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