我正在尝试编译为 32 位嵌入式处理器编写的大型代码库,以便在 64 位桌面处理器上运行以进行模拟/单元测试。我需要生成的对象是一个共享库。这在 Windows 中不是问题,我可以构建这样的 dll (/DWIN32) 并且运行良好。
在 Linux 中,我可以使用 gcc 和链接器的 -m32 选项进行编译和链接,并获得一个共享库。问题是,这个库(就像我用 -m32 指定的一样)是一个 32 位库,不会在我的 64 位拱上运行。使用 Python,我尝试加载库(使用 ctypes.cdll.LoadLibrary())
OSError: out.so: wrong ELF class: ELFCLASS32
我发现了 -mx32 选项,根据文档,这正是我想要的:
-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 的关于这些链接错误的错误报告……但我没有从中看到太多的结论。 这个页面说 gcc 4.8 是 x32 的推荐最低版本,所以我安装了它。仍然-我无法链接。-m32 链接正常。