我想用32位为linux构建一个简单的helloworld C程序。我试着用docker(因为我机器上的操作系统不是Linux(
这是Dockerfile
:
FROM gcc:4.9
RUN dpkg --add-architecture i386
RUN apt-get update && apt-get install -y libc6-dbg libc6-dbg:i386 gcc-multilib libc-dev:i386 gcc-4.9-base:i386
我是这样构建的:
docker build -t my-gcc .
然后我试着这样使用它:
docker run --rm -v ${pwd}:/usr/src/myapp -w /usr/src/myapp my-gcc gcc -m32 -o hello hello.c
我得到这个错误:
/usr/bin/ld: skipping incompatible /usr/local/lib/gcc/x86_64-linux-gnu/4.9.4/libgcc.a when searching for -lgcc
/usr/bin/ld: cannot find -lgcc
/usr/bin/ld: cannot find -lgcc_s
collect2: error: ld returned 1 exit status
我做错了什么?如何修复它?我发现了类似的问题,但它们建议使用我已经安装的gcc-multilib
。
主机是Windows 10 x64,带有WSL2。但据我所知,这应该无关紧要。我想用gcc构建x86 32位linux二进制文件。
以下Dockerfile修复了该问题:
FROM gcc:4.9
RUN apt-get update
&& apt-get install --assume-yes --no-install-recommends --quiet
libc6-dev-i386
gcc-multilib
&& apt-get clean all
ENTRYPOINT ["/usr/bin/gcc-4.9", "-m32"]
测试:
$ docker run --rm -v .:/usr/local/src/:rw my-gcc /usr/local/src/hello.c -o /usr/local/src/hello
$ file hello
hello: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux.so.2, for GNU/Linux 2.6.32, BuildID[sha1]=32f247e8f3406cde7902af8baf469907b42ed969, not stripped
docker镜像提供了两个gcc编译器:
$ docker run --rm -it --entrypoint=bash my-gcc
root@efe1bcf6c715:/# which gcc
/usr/local/bin/gcc
root@efe1bcf6c715:/# which gcc-4.9
/usr/bin/gcc-4.9
如果使用gcc
编译器,我们会得到几个链接器错误:
$ podman run --rm -v .:/usr/local/src/:rw --entrypoint="gcc" my-gcc:latest -m32 /usr/local/src/hello.c -o /usr/local/src/hello
/usr/bin/ld: cannot find crt1.o: No such file or directory
/usr/bin/ld: cannot find crti.o: No such file or directory
/usr/bin/ld: skipping incompatible /usr/local/lib/gcc/x86_64-linux-gnu/4.9.4/libgcc.a when searching for -lgcc
/usr/bin/ld: cannot find -lgcc
/usr/bin/ld: cannot find -lgcc_s
collect2: error: ld returned 1 exit status
强制使用gcc-4.9
,解决了问题。
我使用这个dockerfile:进行了32位编译,以使用gcc 10(在debian上(
FROM debian:bullseye
RUN apt-get update
&& apt-get install --assume-yes --no-install-recommends --quiet
build-essential
gcc-multilib
g++-multilib
autoconf
automake
libtool
正如你所看到的,我还需要各种自动工具。
如果你需要使用configure在32位模式下设置一个工具(在我的情况下是cpbutest(,那么你可以使用这样的参数:
RUN ./configure
CFLAGS=-m32
CXXFLAGS=-m32
LDFLAGS=-m32
--build=x86_64-pc-linux-gnu
--host=i686-pc-linux-gnu
然后,当你像你的问题中那样在容器内编译时,使用gcc和正确的-m32标志,一切都很好地工作,没有错误:
gcc -m32 -O2 main.c -o main.o