通过qemu和docker搭建交叉编译环境

文章介绍了如何使用Docker和QEMU-user在x86_64主机上编译ARM64架构的程序。通过挂载binfmt_misc并配置QEMU静态解释器,可以在容器中创建一个运行不同架构程序的环境,简化了交叉编译的复杂性,包括安装qemu-user-static,下载目标架构的Docker镜像,运行容器,并在容器内进行编译操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

背景

在工作中我们经常需要交叉编译一些可执行程序或者动态库,有时要编译的程序过于复杂,如果靠纯的交叉编译,费事又费力,需要解决大量的编译依赖以及报错。

解决方案 docker + qemu-user

利用qemu-user可以运行不同架构的用户态程序,而docker可以创建一个运行不同架构的用户程序的环境。

原理

这里用到了linux提供的binfmt_misc,可以根据可执行程序的格式来调用不同的处理程序去打开。

参考:linux下使用binfmt_misc设定不同二进制的打开程序

# mount -t binfmt_misc
binfmt_misc on /proc/sys/fs/binfmt_misc type binfmt_misc (rw,nosuid,nodev,noexec,relatime)

# ls /proc/sys/fs/binfmt_misc/
llvm-10-runtime.binfmt  qemu-aarch64  qemu-cris        qemu-mips      qemu-mipsn32    qemu-ppc64abi32  qemu-s390x  qemu-sparc32plus  register
llvm-12-runtime.binfmt  qemu-alpha    qemu-hppa        qemu-mips64    qemu-mipsn32el  qemu-ppc64le     qemu-sh4    qemu-sparc64      status
python2.7               qemu-arm      qemu-m68k        qemu-mips64el  qemu-ppc        qemu-riscv32     qemu-sh4eb  qemu-xtensa
python3.8               qemu-armeb    qemu-microblaze  qemu-mipsel    qemu-ppc64      qemu-riscv64     qemu-sparc  qemu-xtensaeb

# cat /proc/sys/fs/binfmt_misc/qemu-aarch64
enabled
interpreter /usr/bin/qemu-aarch64-static
flags: OCF
offset 0
magic 7f454c460201010000000000000000000200b700
mask ffffffffffffff00fffffffffffffffffeffffff

步骤

下面以在CPU架构为x86_64上Host机器上编译一个目标架构为ARM64的可执行程序为例进行说明。

安装qemu-user

sudo apt install qemu-user-static

下载目标架构的docker镜像

以ubuntu为例,从这个链接中可以找到支持的不同架构的ubuntu镜像,或者从这里可以看到更多的信息。image

安装

sudo docker pull arm64v8/ubuntu

运行容器

$ docker run -it -d -v /usr/bin/qemu-aarch64-static:/usr/bin/qemu-aarch64-static arm64v8/ubuntu:latest
$ docker ps
CONTAINER ID   IMAGE                   COMMAND       CREATED         STATUS         PORTS     NAMES
206e91129cb4   arm64v8/ubuntu:latest   "/bin/bash"   2 seconds ago   Up 2 seconds             eager_northcutt

由于容器运行在一个独立的mount命名空间,而binfmt_misc目录下的qemu-aarch64文件里设置的解析器的路径是:interpreter /usr/bin/qemu-aarch64-static,将来内核也会去同一个mount命名空间里去找/usr/bin/qemu-aarch64-static,因此必须将该解析器映射到容器里。

进入容器

docker exec -it 206e91129cb4 /bin/bash

安装必要的软件包

更新软件

root@206e91129cb4:/# apt update
Get:1 http://ports.ubuntu.com/ubuntu-ports jammy InRelease [270 kB]
Get:2 http://ports.ubuntu.com/ubuntu-ports jammy-updates InRelease [119 kB]
Get:3 http://ports.ubuntu.com/ubuntu-ports jammy-backports InRelease [108 kB]
Get:4 http://ports.ubuntu.com/ubuntu-ports jammy-security InRelease [110 kB]
Get:5 http://ports.ubuntu.com/ubuntu-ports jammy/multiverse arm64 Packages [224 kB]
Get:6 http://ports.ubuntu.com/ubuntu-ports jammy/universe arm64 Packages [17.2 MB]
Get:7 http://ports.ubuntu.com/ubuntu-ports jammy/main arm64 Packages [1758 kB]
Get:8 http://ports.ubuntu.com/ubuntu-ports jammy/restricted arm64 Packages [24.2 kB]
Get:9 http://ports.ubuntu.com/ubuntu-ports jammy-updates/universe arm64 Packages [1096 kB]
Get:10 http://ports.ubuntu.com/ubuntu-ports jammy-updates/restricted arm64 Packages [514 kB]
Get:11 http://ports.ubuntu.com/ubuntu-ports jammy-updates/multiverse arm64 Packages [27.8 kB]
Get:12 http://ports.ubuntu.com/ubuntu-ports jammy-updates/main arm64 Packages [973 kB]
Get:13 http://ports.ubuntu.com/ubuntu-ports jammy-backports/universe arm64 Packages [23.6 kB]
Get:14 http://ports.ubuntu.com/ubuntu-ports jammy-backports/main arm64 Packages [49.0 kB]
Get:15 http://ports.ubuntu.com/ubuntu-ports jammy-security/main arm64 Packages [695 kB]
Get:16 http://ports.ubuntu.com/ubuntu-ports jammy-security/multiverse arm64 Packages [23.4 kB]
Get:17 http://ports.ubuntu.com/ubuntu-ports jammy-security/universe arm64 Packages [846 kB]
Get:18 http://ports.ubuntu.com/ubuntu-ports jammy-security/restricted arm64 Packages [513 kB]
Fetched 24.6 MB in 18s (1375 kB/s)
Reading package lists... Done
Building dependency tree... Done
Reading state information... Done
All packages are up to date.

安装编译器

root@206e91129cb4:/# apt install build-essential

编译的软件包

root@206e91129cb4:~# cd stressapptest-1.0.9
root@206e91129cb4:~/stressapptest-1.0.9# LDFLAGS=--static ./configure
root@206e91129cb4:~/stressapptest-1.0.9# make
root@206e91129cb4:~/stressapptest-1.0.9# file src/stressapptest
src/stressapptest: ELF 64-bit LSB executable, ARM aarch64, version 1 (GNU/Linux), statically linked, BuildID[sha1]=a2496cb7d8610d4bba6ae8744da921fea5b44c53, for GNU/Linux 3.7.0, not stripped

完。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

摩斯电码

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值