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

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

背景

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

解决方案 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镜像,或者从这里可以看到更多的信息。

安装

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

完。

相关文章
|
7月前
|
数据采集 存储 Docker
深入理解Docker:为你的爬虫项目提供隔离环境
本教程介绍如何使用Docker构建隔离环境,运行Python爬虫项目,采集小红书视频页面的简介和评论。主要内容包括: 1. **Docker隔离环境**:通过Docker容器化爬虫,确保环境独立、易于部署。 2. **代理IP技术**:利用亿牛云爬虫代理突破反爬限制。 3. **Cookie与User-Agent设置**:伪装请求头,模拟真实用户访问。 4. **多线程采集**:提高数据采集效率。 前置知识要求:Python基础、Docker基本操作及HTML解析(可选)。教程还涵盖常见错误解决方法和延伸练习,帮助你优化爬虫代码并避免陷阱。
208 7
深入理解Docker:为你的爬虫项目提供隔离环境
|
3月前
|
消息中间件 监控 Docker
Docker环境下快速部署RabbitMQ教程。
就这样,你成功地用魔法召唤出了RabbitMQ,还把它和你的应用程序连接了起来。现在,消息会像小溪流水一样,在你的系统中自由流淌。别忘了,兔子们不喜欢孤独,他们需要你细心的关怀,不时地监控它们,确保他们的世界运转得井井有条。
210 18
|
3月前
|
Ubuntu 机器人 开发者
Docker环境下的ROS Noetic:Ubuntu 20.04 系统下的解决方案
这就是在Docker环境下安装ROS Noetic在Ubuntu 20.04系统的一种简单方法,希望能对你有所帮助。
350 16
|
5月前
|
关系型数据库 MySQL Linux
在Linux环境下备份Docker中的MySQL数据并传输到其他服务器以实现数据级别的容灾
以上就是在Linux环境下备份Docker中的MySQL数据并传输到其他服务器以实现数据级别的容灾的步骤。这个过程就像是一场接力赛,数据从MySQL数据库中接力棒一样传递到备份文件,再从备份文件传递到其他服务器,最后再传递回MySQL数据库。这样,即使在灾难发生时,我们也可以快速恢复数据,保证业务的正常运行。
250 28
|
4月前
|
算法 Shell 定位技术
在Docker环境下搭建openvslam/orb_slam3的步骤和问题总结
总的来说,搭建openvslam或orb_slam3的过程需要一些耐心和技术知识,但只要你遵循上述步骤,并且在遇到问题时进行适当的调试,你应该能够成功搭建并运行openvslam或orb_slam3。
189 11
|
9月前
|
Ubuntu Linux Shell
(已解决)Linux环境—bash: wget: command not found; Docker pull报错Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: request canceled
(已成功解决)Linux环境报错—bash: wget: command not found;常见Linux发行版本,Linux中yum、rpm、apt-get、wget的区别;Docker pull报错Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: request canceled
3911 68
(已解决)Linux环境—bash: wget: command not found; Docker pull报错Error response from daemon: Get https://registry-1.docker.io/v2/: net/http: request canceled
|
6月前
|
Java API Docker
在线编程实现!如何在Java后端通过DockerClient操作Docker生成python环境
以上内容是一个简单的实现在Java后端中通过DockerClient操作Docker生成python环境并执行代码,最后销毁的案例全过程,也是实现一个简单的在线编程后端API的完整流程,你可以在此基础上添加额外的辅助功能,比如上传文件、编辑文件、查阅文件、自定义安装等功能。 只有锻炼思维才能可持续地解决问题,只有思维才是真正值得学习和分享的核心要素。如果这篇博客能给您带来一点帮助,麻烦您点个赞支持一下,还可以收藏起来以备不时之需,有疑问和错误欢迎在评论区指出~
在线编程实现!如何在Java后端通过DockerClient操作Docker生成python环境
|
9月前
|
负载均衡 网络协议 算法
Docker容器环境中服务发现与负载均衡的技术与方法,涵盖环境变量、DNS、集中式服务发现系统等方式
本文探讨了Docker容器环境中服务发现与负载均衡的技术与方法,涵盖环境变量、DNS、集中式服务发现系统等方式,以及软件负载均衡器、云服务负载均衡、容器编排工具等实现手段,强调两者结合的重要性及面临挑战的应对措施。
290 3
|
10月前
|
关系型数据库 MySQL Docker
docker环境下mysql镜像启动后权限更改问题的解决
在Docker环境下运行MySQL容器时,权限问题是一个常见的困扰。通过正确设置目录和文件的权限,可以确保MySQL容器顺利启动并正常运行。本文提供了多种解决方案,包括在主机上设置正确的权限、使用Dockerfile和Docker Compose进行配置、在容器启动后手动更改权限以及使用 `init`脚本自动更改权限。根据实际情况选择合适的方法,可以有效解决MySQL容器启动后的权限问题。希望本文对您在Docker环境下运行MySQL容器有所帮助。
1753 1
|
11月前
|
网络安全 虚拟化 Docker
SSH后判断当前服务器是云主机、物理机、虚拟机、docker环境
结合上述方法,您可以对当前环境进行较为准确的判断。重要的是理解每种环境的特征,并通过系统的响应进行综合分析。如果在Docker容器内,通常会有明显的环境标志和受限的资源视图;而在云主机或虚拟机上,虽然它们也可能是虚拟化的,但通常提供更接近物理机的体验,且可通过硬件标识来识别虚拟化平台。物理机则直接反映硬件真实信息,较少有虚拟化痕迹。通过这些线索,您应该能够定位到您所处的环境类型。
474 2