docker gcc容器中进行交叉编译
前言
前提
已安装好docker
本文涉及的环境信息:
- 操作系统 :Linux x86_64
- docker :Docker version 18.09.0, build d1134d1
docker 安装可参考如下操作:
maven安装
(1) 配置源并安装:
sudo wget http://repos.fedorapeople.org/repos/dchen/apache-maven/epel-apache-maven.repo -O /etc/yum.repos.d/epel-apache-maven.repo
sudo sed -i s/\$releasever/6/g /etc/yum.repos.d/epel-apache-maven.repo
sudo yum install -y apache-maven
(2) 修改配置文件添加阿里云的镜像地址,配置仓库位置:
vim /usr/share/apache-maven/conf/settings.xml
修改内容:
<mirror>
<id>alimaven</id>
<name>aliyun maven</name>
<url>http://maven.aliyun.com/nexus/content/groups/public/</url>
<mirrorOf>central</mirrorOf>
</mirror>
配置仓库位置:
<localRepository>/cicro/var/m2/repo</localRepository>
Docker安装
配置要求:
- CentOS内核3.10以上。使用
uname -r
查看内核版本。 yum
更新到最新版本。使用sudo yum update
更新。更新过程中需要输入Y
指令。
(1)安装依赖的软件包yum-utils
,device-mapper-persistent-data
和lvm2
。使用命令:
sudo yum install -y yum-utils device-mapper-persistent-data lvm2
(2)映射仓库地址。
sudo yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
(3)安装docker引擎。sudo yum install docker-ce docker-ce-cli containerd.io
(官方教程要安装docker-compose-plugin,以进行管理,但安装后会出现问题,可暂不安装此插件)。安装过程中需要输入Y
指令。可默认全yes安装命令如下:
sudo yum install docker-ce docker-ce-cli containerd.io -y
(4)查看docker版本:docker version
(5)启动:sudo systemctl start docker.service
。如需设置开机启动,可使用命令sudo systemctl enable docker.service
。
(6)测试是否成功:sudo docker run hello-world
。等待一下,此命令会下载测试映像并在容器中运行它。当容器运行时,它会打印一条消息并退出。
问题解决:
- 启动docker提示
unit not found
。
卸载第(3)步,重新安装 。
卸载:
sudo yum remove docker-ce docker-ce-cli containerd.io docker-compose-plugin
sudo rm -rf /var/lib/docker
sudo rm -rf /var/lib/containerd
下载gcc 镜像
gcc镜像官方可下载版本查看地址:https://hub.docker.com/_/gcc/tags?page=1
默认获取最新版本
docker pull gcc
如果需要指定gcc版本,则如下
docker pull gcc:7.5.0
运行gcc容器
命令:docker run -it -u root --name {容器名称} -v {宿主机挂载目录}:{容器内目录} {镜像}
使用默认最新版本的gcc镜像:
docker run -it -u root --name {容器名称} -v {宿主机挂载目录}:/var/home gcc
使用指定版本的gcc镜像:
docker run -it -u root --name {容器名称} -v {宿主机挂载目录}:/var/home gcc:7.5.0
交叉编译工具链
采用:arm-linux-gcc4.4.3
下载地址:http://www.arm9.net/download.asp
步骤
- 解压并复制到容器目录内(宿主机中操作)
- 添加工具地址到path(容器内操作)
- 查看版本以测试是否可用(容器内操作)
tar -ivxzf arm-linux-gcc-4.4.3.tar.gz -C ./
copy
export PATH=$PATH:/var/home/arm-linux-gcc-4.4.3/bin
arm-linux-gcc -v
编译与安装示例(busybox)
busybox 下载:
wget https://busybox.net/downloads/busybox-1.35.0.tar.bz2
tar -xf busybox-1.35.0.tar.bz2
本文示例为1.31.0版本:
wget https://busybox.net/downloads/busybox-1.31.0.tar.bz2
tar -xf busybox-1.31.0.tar.bz2
busybox交叉编译与安装
步骤
- 安装依赖库
- 切换至busybox目录
- 设置默认编译配置
- 自定义编译配置
- 编译并设置编译方式及编译工具链
apt-get install lib32stdc++6
cd /var/home/busybox-1.31.0
make defconfig
make menuconfig
执行 make menuconfig
后进入图形化配置界面,如下:
配置路径 | 是否加入配置 | 说明 |
---|---|---|
-> Settings -> Build static binary (no shared libs) | 否 | 配置动态编译 |
->Coreutils ->sync | 否 | |
-> Linux Module Utilities -> Simplified modutils | 否 | |
->Linux system Utilities ->nsenter | 否 |
编译命令如下:
make ARCH=arm CROSS_COMPILE=arm-linux-
参数说明
ARCH
:指定架构,示例为arm架构CROSS_COMPILE
:指定编译工具链
编译成功后查看,会有一个busybox安装包:
上图是容器内查看,没有颜色标记,切换到宿主机的挂载目录中查看:
作为对比,下图是编译前包中的目录结构 :
busybox非交叉编译与安装(x86架构编译)
本机环境x86,编译x86架构使用的。
步骤
- 安装依赖库
- 切换至busybox目录
- 设置默认编译配置
- 自定义编译配置
- 编译并设置编译方式及编译工具链
- 安装及配置环境变量
apt-get install lib32stdc++6
cd /var/home/busybox-1.31.0
make defconfig
make
make install CONFIG_PREFIX=/bin/busybox
export PATH=$PATH:/bin/busybox/bin
参数说明
CONFIG_PREFIX
:指定安装路径
关于版本选择
由于glibc在2.31时已经去掉了stime。如果需要使用stime的,需注意版本选择。
例如busybox1.31.0版本需要stime,那么glibc不能使用2.31,具体是多少版本以前暂不清楚,但是2.28的版本是可用的。
查看glibc版本命令:ldd --version
查看gcc版本命令:gcc -v
依赖安装前请先更新:apt-get update
以下为gcc镜像版本、gcc镜像默认使用的glibc版本、使用交叉编译工具链需要安装的依赖:
gcc镜像版本 | 默认使用的glibc版本 | arm-linux-gcc-4.4.3需要安装的类库 |
---|---|---|
10-10.2.1 | 2.31 | libc6-i386 lib32stdc++6 lib32z1 ncurses-dev |
12.2.0 | 2.31 | |
7.5.0 | 2.28 | lib32z1 ncurses-dev |
类库说明:
lib32z1
:64位操作系统兼容32位交叉编译工具链
busybox testsuite
编译
同busybox编译
执行
编译后切换至testsuite目录,此时测试的是本包中的busybox。
如需用于测试非本包中的busybox。例如开发板上已经装好的busybox。
可将编译后的.config文件和testsuite目录一并拷贝到busybox安装文件所在目录。注意要与busybox安装文件在同一目录下。
再切换到testsuite目录中执行。
执行命令:
mkdir ../test_result
now_time=`date +%Y%m%d_%H%M%S`
./runtest >../test_result/test_result_${now_time}.txt 2> ../test_result/test_error_${now_time}.txt
标准输出到上一层目录下的test_result.txt
错误输出到上一层目录下的test_error.txt