Dockerfile构建riscv-gnu-toolchain镜像
elf-gcc
基于ubuntu 22.04构建
vim Dockerfile
# 使用官方的 Ubuntu 22.04 镜像作为基础镜像
FROM ubuntu:22.04
# 设置镜像的维护者信息
LABEL maintainer="qymlyl"
# 用户默认是root,目录默认是/,WORKDIR设置默认的工作目录
WORKDIR /opt/source
# 运行更新命令以获取最新的软件包列表并安装必要的工具
RUN apt-get update && \
apt-get upgrade -y && \
apt-get install -y openssh-server vim autoconf automake autotools-dev curl python3 python3-pip libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev ninja-build git cmake libglib2.0-dev libpixman-1-0 libpixman-1-dev
# clone riscv-gun-tool及子模块
RUN curl https://mirror.iscas.ac.cn/riscv-toolchains/git/riscv-collab/riscv-gnu-toolchain.sh | bash
# 编译riscv-gnu-toolchain
# --enable-multilib:构建支持 32 位和 64 位的交叉编译器
RUN cd riscv-gnu-toolchain && \
./configure --prefix=/opt/riscv --enable-multilib && \
make -j$(nproc) && \
make -j$(nproc) build-sim SIM=qemu QEMU_TARGETS=riscv64-linux-user,riscv32-linux-user,riscv64-softmmu,riscv32-softmmu
# 设置 RISCV变量
RUN echo 'export RISCV=/opt/riscv' >> /etc/profile && \
echo 'export PATH=$RISCV/bin:$PATH' >> /etc/profile && \
/bin/bash -c 'source /etc/profile' && \
echo 'export RISCV=/opt/riscv' >> ~/.bashrc && \
echo 'export PATH=$RISCV/bin:$PATH' >> ~/.bashrc && \
/bin/bash -c 'source ~/.bashrc'
# 将默认工作目录设置在/
WORKDIR /
# 删除源码
RUN rm -rf /opt/source
# 定义容器启动时运行的命令
CMD ["bash"]
构建镜像
# 构建新的版本时注意清除构建缓存
docker builder prune
# 基于amd64 ubuntu22.04镜像构建的支持riscv64和riscv32两种架构的elf-gcc和qemu
# 拉取的是官方最新的代码
# 这里对应官方2024/7/3的提交, commitid: 1358115963fb55cc445535d8a931e2f51dbe1940
nohup docker build -t riscv-gnu-toolchain:elf_gcc_qemu_HEADE_1358115 . &
镜像压缩
# 未压缩之前20G(包含源码层),压缩后2G
docker-squash riscv-gnu-toolchain:elf_gcc_qemu_HEADE_1358115 \
-t riscv-gnu-toolchain:elf_gcc_qemu_HEADE_1358115_squashed
glibc-gcc
基于ubuntu 22.04构建
# 使用官方的 Ubuntu 22.04 镜像作为基础镜像
FROM ubuntu:22.04
# 设置镜像的维护者信息
LABEL maintainer="qymlyl"
# 用户默认是root,目录默认是/,WORKDIR设置默认的工作目录
WORKDIR /opt/source
# 运行更新命令以获取最新的软件包列表并安装必要的工具
RUN apt-get update && \
apt-get upgrade -y && \
apt-get install -y openssh-server vim autoconf automake autotools-dev curl python3 python3-pip libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev ninja-build git cmake libglib2.0-dev libpixman-1-0 libpixman-1-dev
# clone riscv-gun-tool及子模块
RUN curl https://mirror.iscas.ac.cn/riscv-toolchains/git/riscv-collab/riscv-gnu-toolchain.sh | bash
# 编译riscv-gnu-toolchain
# --enable-multilib:构建支持 32 位和 64 位的交叉编译器
RUN cd riscv-gnu-toolchain && \
./configure --prefix=/opt/riscv --enable-multilib && \
make linux -j$(nproc) && \
make -j$(nproc) build-sim SIM=qemu QEMU_TARGETS=riscv64-linux-user,riscv32-linux-user,riscv64-softmmu,riscv32-softmmu
# 设置 RISCV变量
RUN echo 'export RISCV=/opt/riscv' >> /etc/profile && \
echo 'export PATH=$RISCV/bin:$PATH' >> /etc/profile && \
/bin/bash -c 'source /etc/profile' && \
echo 'export RISCV=/opt/riscv' >> ~/.bashrc && \
echo 'export PATH=$RISCV/bin:$PATH' >> ~/.bashrc && \
/bin/bash -c 'source ~/.bashrc'
# 将默认工作目录设置在home目录
WORKDIR /
# 定义容器启动时运行的命令
CMD ["bash"]
构建镜像
# 构建新的版本时注意清除构建缓存
docker builder prune
nohup docker build -t riscv-gnu-toolchain:glibc_gcc_qemu_HEADE_1358115 . &
镜像压缩
# 未压缩之前20G(包含源码层),压缩后2G
docker-squash riscv-gnu-toolchain:glibc_gcc_qemu_HEADE_13581155 \
-t riscv-gnu-toolchain:glibc_gcc_qemu_HEADE_1358115_squashed
musl-gcc
基于ubuntu 22.04构建
# 使用官方的 Ubuntu 22.04 镜像作为基础镜像
FROM ubuntu:22.04
# 设置镜像的维护者信息
LABEL maintainer="qymlyl"
# 用户默认是root,目录默认是/,WORKDIR设置默认的工作目录
WORKDIR /opt/source
# 运行更新命令以获取最新的软件包列表并安装必要的工具
RUN apt-get update && \
apt-get upgrade -y && \
apt-get install -y openssh-server vim autoconf automake autotools-dev curl python3 python3-pip libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev ninja-build git cmake libglib2.0-dev libpixman-1-0 libpixman-1-dev
# clone riscv-gun-tool及子模块
RUN curl https://mirror.iscas.ac.cn/riscv-toolchains/git/riscv-collab/riscv-gnu-toolchain.sh | bash
# 编译riscv-gnu-toolchain
# --enable-multilib:构建支持 32 位和 64 位的交叉编译器(对于mul并没有起作用,mul只支持64位架构)
RUN cd riscv-gnu-toolchain && \
./configure --prefix=/opt/riscv --enable-multilib && \
make musl -j$(nproc) && \
make -j$(nproc) build-sim SIM=qemu QEMU_TARGETS=riscv64-linux-user,riscv32-linux-user,riscv64-softmmu,riscv32-softmmu
# 设置 RISCV变量
RUN echo 'export RISCV=/opt/riscv' >> /etc/profile && \
echo 'export PATH=$RISCV/bin:$PATH' >> /etc/profile && \
/bin/bash -c 'source /etc/profile' && \
echo 'export RISCV=/opt/riscv' >> ~/.bashrc && \
echo 'export PATH=$RISCV/bin:$PATH' >> ~/.bashrc && \
/bin/bash -c 'source ~/.bashrc'
# 将默认工作目录设置在home目录
WORKDIR /
# 定义容器启动时运行的命令
CMD ["bash"]
构建镜像
# 构建新的版本时注意清除构建缓存
docker builder prune
nohup docker build -t riscv-gnu-toolchain:musl_gcc_qemu_HEADE_1358115 . &
镜像压缩
docker-squash riscv-gnu-toolchain:musl_gcc_qemu_HEADE_1358115 -t riscv-gnu-toolchain:musl_gcc_qemu_HEADE_1358115_squashed
启动示例
以elf_gcc为例
创建容器
# riscv toolchain是基于ubuntu 22.04镜像进行构建,这里设置一个端口与22端口进行映射便于使用ssh链接
docker run --name riscv64_elf_gcc \
-p 10022:22 \
-itd mqylyl/riscv-gnu-toolchain:elf_gcc_qemu_HEADE_1358115
进入容器
docker exec -it riscv64_elf_gcc /bin/bash
查看版本信息
$ riscv64-unknown-elf-gcc -v
Using built-in specs.
COLLECT_GCC=riscv64-unknown-elf-gcc
COLLECT_LTO_WRAPPER=/opt/riscv/libexec/gcc/riscv64-unknown-elf/13.2.0/lto-wrapper
Target: riscv64-unknown-elf
Configured with: /opt/source/riscv-gnu-toolchain/gcc/configure --target=riscv64-unknown-elf --prefix=/opt/riscv --disable-shared --disable-threads --enable-languages=c,c++ --with-pkgversion=gc891d8dc23e --with-system-zlib --enable-tls --with-newlib --with-sysroot=/opt/riscv/riscv64-unknown-elf --with-native-system-header-dir=/include --disable-libmudflap --disable-libssp --disable-libquadmath --disable-libgomp --disable-nls --disable-tm-clone-registry --src=.././gcc --enable-multilib --with-abi=lp64d --with-arch=rv64imafdc --with-tune=rocket --with-isa-spec=20191213 'CFLAGS_FOR_TARGET=-Os -mcmodel=medlow' 'CXXFLAGS_FOR_TARGET=-Os -mcmodel=medlow'
Thread model: single
Supported LTO compression algorithms: zlib
gcc version 13.2.0 (gc891d8dc23e)
$ qemu-system-riscv64 -version
QEMU emulator version 8.1.1 (v8.1.1)
Copyright (c) 2003-2023 Fabrice Bellard and the QEMU Project developers
编译运行C程序(hello_world.c)
编写hello_world.c文件
echo '#include <stdio.h>' > hello_world.c && \
echo 'int main() {' >> hello_world.c && \
echo ' printf("Hello, world!\n");' >> hello_world.c && \
echo ' return 0;' >> hello_world.c && \
echo '}' >> hello_world.c
编译运行riscv64
# 编译
$ riscv64-unknown-elf-gcc -march=rv64imafdc -mabi=lp64 -o hello_world_64 hello_world.c
# 查看二进制文件格式,64-bit
$ file hello_world_64
hello_world_64: ELF 64-bit LSB executable, UCB RISC-V, RVC, soft-float ABI, version 1 (SYSV), statically linked, with debug_info, not stripped
# 使用qemu运行程序
# qemu-riscv64:user mode运行
# -L: 用于加载模拟器的体系结构支持文件的目录(risc-v的一些库都在$RISCV/sysroot目录下)
# qemu-riscv64 -L $RISCV/sysroot ./hello_world_64
$ qemu-riscv64 ./hello_world_64
hello world!
编译运行riscv32
# 编译
$ riscv64-unknown-elf-gcc -march=rv32imafdc -mabi=ilp32 -o hello_world_32 hello_world.c
# 查看二进制文件格式,32-bit
$ file hello_world_32
hello_world_32: ELF 32-bit LSB executable, UCB RISC-V, RVC, soft-float ABI, version 1 (SYSV), statically linked, with debug_info, not strippe
# 运行
$ qemu-riscv32 ./hello_world_32
hello world!
二进制程序和源码目录
二进制程序放在在/opt/riscv
问题
镜像太大了
$ docker images riscv-gnu-toolchain:riscv6432_elf_gcc_qemu_20231018_nightly_ubuntu2204_arm64
REPOSITORY TAG IMAGE ID CREATED SIZE
riscv-gnu-toolchain riscv6432_elf_gcc_qemu_20231018_nightly_ubuntu2204_arm64 e272d8d35157 About an hour ago 22.1GB
$ docker history riscv-gnu-toolchain:riscv6432_elf_gcc_qemu_20231018_nightly_ubuntu2204_arm64
IMAGE CREATED CREATED BY SIZE COMMENT
e272d8d35157 About an hour ago CMD ["bash"] 0B buildkit.dockerfile.v0
<missing> About an hour ago WORKDIR / 0B buildkit.dockerfile.v0
<missing> About an hour ago RUN /bin/sh -c echo 'export RISCV=/opt/riscv… 3.79kB buildkit.dockerfile.v0
<missing> About an hour ago RUN /bin/sh -c cd riscv-gnu-toolchain && … 12.1GB buildkit.dockerfile.v0
<missing> 7 hours ago RUN /bin/sh -c curl https://mirror.iscas.ac.… 9.42GB buildkit.dockerfile.v0
<missing> 9 hours ago RUN /bin/sh -c apt-get update && apt-get… 528MB buildkit.dockerfile.v0
<missing> 9 hours ago WORKDIR /opt/source 0B buildkit.dockerfile.v0
<missing> 9 hours ago LABEL maintainer=qymlyl 0B buildkit.dockerfile.v0
<missing> 3 weeks ago /bin/sh -c #(nop) CMD ["/bin/bash"] 0B
<missing> 3 weeks ago /bin/sh -c #(nop) ADD file:f8594e26831508c31… 69.2MB
<missing> 3 weeks ago /bin/sh -c #(nop) LABEL org.opencontainers.… 0B
<missing> 3 weeks ago /bin/sh -c #(nop) LABEL org.opencontainers.… 0B
<missing> 3 weeks ago /bin/sh -c #(nop) ARG LAUNCHPAD_BUILD_ARCH 0B
<missing> 3 weeks ago /bin/sh -c #(nop) ARG RELEASE 0B
source: not found
> [6/6] RUN echo 'export RISCV=/opt/riscv' >> /etc/profile && echo 'export PATH=$RISCV/bin:$PATH' >> /etc/profile && source /etc/profile && echo 'export RISCV=/opt/riscv' >> ~/.bashrc && echo 'export PATH=$RISCV/bin:$PATH' >> ~/.bashrc && source ~/.bashrc:
0.296 /bin/sh: 1: source: not found
------
解决方案:使用/bin/bash -c source
Dependency "pixman-1" not found
编译Qemu时遇到
un-time dependency pixman-1 found: NO (tried pkgconfig)
../qemu/meson.build:840:11: ERROR: Dependency "pixman-1" not found, tried pkgconfig
A full log can be found at /home/parallels/Wokspace/study/riscv/riscv-gnu-toolchain/build-qemu/meson-logs/meson-log.txt
ERROR: meson setup failed
make: *** [Makefile:903: stamps/build-qemu] Error 1
解决方案:
sudo apt-get install libpixman-1-0 libpixman-1-dev