【发布时间】:2016-01-18 08:47:39
【问题描述】:
我正在尝试编译为 32 位嵌入式处理器编写的大型代码库,以便在 64 位桌面处理器上运行以进行模拟/单元测试。我需要生成的对象是一个共享库。这在 Windows 中不是问题,我可以像这样 (/DWIN32) 构建一个 dll,它运行良好。
在 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 链接正常。
【问题讨论】:
-
假设您确实需要
ELF 64-bits,链接器似乎无法找到 glibc 提供的 libm.so。可以在库路径中添加/usr/lib64吗? -
感谢@alvits 的回复,但是我没有这个目录:
$ cd /usr/lib64 bash: cd: /usr/lib64: No such file or directory
标签: linux gcc x86-64 32bit-64bit linux-x32-abi