RISC-V GNU Toolchain工具链
一、GNU 工具链内容
工具链包含以下内容:
- gcc(GNU C Compiler):编译器
- C运行库:包括glibc、newlib、musl三种运行库,为C标准库提供函数实现支持,可以根据需求进行自定义修改。
- Binutils:二进制程序处理工具,包括ar(静态库处理)、as(汇编器)、ld(链接器)等。
- GDB:用于项目调试。
- DeJaGNU:程序测试框架,为所有测试提供一个前端支持。
二、运行时库
riscv-gnu-toolchain 工具链分为elf-gcc和linux-gnu-gcc两个版本,以及他们对应的32位和64位版本。两个的主要区别在于:
- elf-gcc:(riscv32-unknown-elf-*,riscv64-unknown-elf-*)使用的newlib库(面向嵌入式的C库),而且只支持静态链接,不支持动态链接。
- linux-gnu-gcc:(riscv32-unknown-linux-gnu-*,riscv64-unknown-linux-gnu-*)使用的是glibc标准库,支持动态链接。
从名字上便可以区分两者的使用场景,如果是编译简单,较小的elf程序,使用elf-gcc版本即可,如果编译比较大的程序或者需要动态库(比如编译linux,或opencv库等),推荐使用linux-gnu-gcc版本。
newlib
newlib是redhat社区维护的一个C运行时库,与glibc相比,其最大的特点是代码体积小、可移植性强,特别适合嵌入式开发环境。
例如,newlib重写了printf、scanf、malloc函数,减少调用开销;并默认开启-Os编译开关,对代码体积进行压缩。
glibc
musl
三、Binutils工具介绍
- as:汇编器
- ld:链接器
- ar:生成静态链接库
- ldd:查看一个可执行程序所需要的依赖库
- size:查看一个可执行程序各部分的大小(数据段、代码段等)
四、安装步骤
Step 1:安装依赖工具
1 | sudo apt-get install git autoconf automake autotools-dev curl python3 libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf patchutils bc libexpat-dev libglib2.0-dev ninja-build zlib1g-dev pkg-config libboost-all-dev libtool libssl-dev libpixman-1-dev libpython-dev virtualenv libmount-dev libsdl2-dev |
Step 2:下载riscv工具链
github项目:riscv-collab/riscv-gnu-toolchain: GNU toolchain for RISC-V, including GCC (github.com)
1 | git clone https://github.com/riscv-collab/riscv-gnu-toolchain.git |
**gitee项目:**https://gitee.com/mirrors/riscv-dejagnu
1 | git clone https://gitee.com/mirrors/riscv-gnu-toolchain |
ps:最好用github,它是最新的
Step 3:下载各种submodule
下载 RISC-V 平台的 C 语言编译器源代码仓库
1 | git clone -b riscv-gcc-10.2.0 https://gitee.com/mirrors/riscv-gcc |
下载测试框架源代码仓库,即 riscv-dejagnu
1 | git clone https://gitee.com/mirrors/riscv-dejagnu |
下载 GNU 的 C 库源代码仓库,也就是 riscv-glibc
1 | git clone -b riscv-glibc-2.29 https://gitee.com/mirrors/riscv-glibc |
下载用于嵌入式的轻量级 C 库源代码仓库,即 riscv-newlib
1 | git clone https://gitee.com/mirrors/riscv-newlib |
下载二进制工具集合源代码仓库 riscv-binutils
1 | git clone -b riscv-binutils-2.35 https://gitee.com/mirrors/riscv-binutils-gdb riscv-binutils |
下载 GDB 软件调试器源代码仓库 riscv-gdb
1 | git clone -b fsf-gdb-10.1-with-sim https://gitee.com/mirrors/riscv-binutils-gdb riscv-gdb |
Step 3:使用./configure进行配置
1 | ./configure --prefix=xxx --with-arch=xxx --with-abi=xxx |
(–prefix=)选项
安装后的目标文件夹
例如--prefix=/opt/riscv/
,则安装后的可执行文件如下:
(–with-arch=)选项
由于RISC-V的指令集是模块化的指令集,因此在为目标RISC-V平台进行交叉编译之时,需要通过选项指定目标RISC-V平台所支持的模块化指令集组合,该选项为(-march=),有效的选项值如下:
- rv32i[m][a][f[d]][c]
- rv32g[c]
- rv64i[m][a][f[d]][c]
- rv64g[c]
注意:在上述选项中rv32表示目标平台是32位架构,rv64表示目标平台是64位架构,其他i/m/a/f/d/c/g分别代表了RISC-V模块化指令子集的字母简称。
(–with-abi=)选项
由于RISC-V的指令集是模块化的指令集,因此在为目标RISC-V平台进行交叉编译之时,需要通过选项指定嵌入式RISC-V目标平台所支持的ABI函数调用规则
RISC-V定义了两种整数的ABI调用规则和三种浮点ABI调用规则,通过选项(-abi=)指明,有效的选项值如下:
- ilp32
- ilp32f
- ilp32d
- lp64
- lp64f
- lp64d
在上述选项中两种前缀(ilp32和lp64)表示的含义如下:
- 前缀ilp32表示目标平台是32位架构,在此架构下,C语言的“int”和“long”变量长度为32比特,“long long”变量为64位;
- 前缀lp64表示目标平台是64位架构,C语言的“int”变量长度为32比特,而“long”变量长度为64比特。
上述选项中的三种后缀类型(无后缀、后缀f、后缀d)表示的含义如下:
- 无后缀:在此架构下,如果使用了浮点类型的操作,直接使用RISC-V浮点指令进行支持。但是当浮点数作为函数参数进行传递之时,无论单精度浮点数还是双精度浮点数均需要通过存储器中的堆栈进行传递。
- f:表示目标平台支持硬件单精度浮点指令。在此架构下,如果使用了浮点类型的操作,直接使用RISC-V浮点指令进行支持。但是当浮点数作为函数参数进行传递之时,单精度浮点数可以直接通过寄存器传递,而双精度浮点数需要通过存储器中的堆栈进行传递。
- d:表示目标平台支持硬件双精度浮点指令。在此架构下,如果使用了浮点类型的操作,直接使用RISC-V浮点指令进行支持。当浮点数作为函数参数进行传递之时,无论单精度还是双精度浮点数都可以直接通过寄存器传递。
Step 4:使用make命令进行构建
make
、make all
、make newlib
命令构建使用newlib的elf-gcc
make linux
命令构建使用glibc的linux-gnu-gcc
开启-j
选项可以启动多线程编译
Step 5 设置环境变量
在~/.bashrc
文件末尾加入以下语句来将(yourtpath)路径加入环境变量
1 | export PATH=$PATH:(yourpath) |
再在终端中执行以下命令更新环境变量
1 | source ~/.bashrc |
Step 6 检查配置
通过相应gcc的-v命令,可以得到该工具链的配置信息,例如:
1 | $ riscv32-unknown-elf-gcc -v |
可以看出
1 | --target=riscv32-unknown-elf: 指定工具为riscv32-unknow-elf |
常用配置下RISCV工具链配置与编译
riscv32-unknown-elf-gcc
1
2./configure --prefix=/opt/riscv32 --with-arch=rv32imc --with-abi=lp32
make编译完成后,在/opt/riscv32/bin目录下,有riscv32-unknown-elf-gcc的所有工具。
riscv64-unknown-elf-gcc
1
2./configure --prefix=/opt/riscv64 --with-arch=rv64imc --with-abi=lp64
make编译完成后,在/opt/riscv64/bin目录下,有riscv64-unknown-elf-gcc的所有工具。
riscv32-unknown-linux-gnu-gcc
1
2./configure --prefix=/opt/riscv32-linux --with-arch=rv32imc --with-abi=ilp32 --enable-linux
make linux编译完成后,在/opt/riscv32-linux/bin目录下,有riscv32-unknown-linux-gnu-gcc的所有工具。
riscv64-unknown-linux-gnu-gcc
1
2./configure --prefix=/opt/riscv64-linux --with-arch=rv64imafdc --with-abi=lp64 --enable-linux
make linux编译完成后,在/opt/riscv64-linux/bin目录下,有riscv64-unknown-linux-gnu-*的所有工具。
构建默认riscv工具链的全部命令
1 | sudo apt-get install git autoconf automake autotools-dev curl python3 libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf patchutils bc libexpat-dev libglib2.0-dev ninja-build zlib1g-dev pkg-config libboost-all-dev libtool libssl-dev libpixman-1-dev libpython-dev virtualenv libmount-dev libsdl2-dev |
参考博客
riscv-gnu-toolchain 交叉编译器如何构建? - 知乎 (zhihu.com)https://blog.csdn.net/u014558361/article/details/135372254)
riscv-gnu-toolchain工具链-从下载到运行_riscv toolchain-CSDN博客
参考视频