问题描述
我正在尝试使用gcc 4.8在Ubuntu Server 12.04 LTS 64位上编译32位C应用程序。我收到有关不兼容库和skipping -lgcc
的链接器错误消息。我需要怎么做才能编译和链接32位应用程序?
最佳回答
Ubuntu 16.04
sudo apt-get install gcc-multilib
由于某种原因,在Ubuntu 17.04上,我还需要安装特定于该版本的版本:
sudo apt-get install gcc-6-multilib
然后是一个最小的问候世界:
main.c
#include <stdio.h>
int main(void) {
puts("hello world");
return 0;
}
无需警告即可编译:
gcc -m32 -ggdb3 -O0 -pedantic-errors -std=c89 \
-Wall -Wextra -pedantic -o main.out main.c
和
./main.out
输出:
hello world
和:
file main.out
说:
main.out: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.24, BuildID[sha1]=87c87a83878ce7e7d23b6236e4286bf1daf59033, not stripped
和:
qemu-i386 main.out
还给出:
hello world
但是在x86_64
可执行文件上失败,并显示以下内容:
./main.out: Invalid ELF image for this architecture
此外,我有:
-
在32位VM中运行编译的文件
所以我认为这是可行的:-)
另请参阅:Cannot find crtn.o, linking 32 bit code on 64 bit system
令人遗憾的是,此软件包与诸如gcc-arm-linux-gnueabihf
https://bugs.launchpad.net/ubuntu/+source/gcc-defaults/+bug/1300211之类的交叉编译器冲突
问题的运行版本:
我们能够直接在64位Ubuntu上运行32位程序,因为Ubuntu内核配置为:
CONFIG_IA32_EMULATION=y
根据:
grep CONFIG_IA32_EMULATION "/boot/config-$(uname -r)"
在kernel source tree上的帮助如下:
Include code to run legacy 32-bit programs under a
64-bit kernel. You should likely turn this on, unless you're
100% sure that you don't have any 32-bit programs left.
这又有可能,因为x86 64位CPU具有运行Linux内核使用的32位程序的模式。
待办事项:gcc-multilib
的编译方式与gcc
的编译方式不同吗?
次佳回答
要使Ubuntu Server 12.04 LTS 64位编译gcc 4.8 32位程序,您需要做两件事。
-
确保已完全安装所有32位gcc 4.8开发工具:
sudo apt-get install lib32gcc-4.8-dev
-
使用-m32标志
gcc pgm.c -m32 -o pgm
编译程序
第三种回答
通过将体系结构信息添加到要安装的程序包名称中,可以支持多体系结构安装(而不是使用可能会或可能不可用的备用名称安装这些程序包)。
有关(现代)多体系结构安装的更多信息,请参见this answer。
在您的情况下,最好安装32位gcc和libc:
sudo apt-get install libc6-dev:i386 gcc:i386
它将在您的64位安装旁边安装32位libc开发和gcc软件包以及所有依赖的软件包(所有32位版本),而不会破坏它。