14 Star 80 Fork 38

aosp-riscv / working-group

Create your Gitee Account
Explore and code with more than 12 million developers,Free private repositories !:)
Sign up
This repository doesn't specify license. Please pay attention to the specific project description and its upstream code dependency when using it.
Clone or Download
20220721-riscv-gcc.md 10.77 KB
Copy Edit Raw Blame History
unicornx authored 2023-06-26 19:34 . improve rv gcc, continue

文章标题:制作交叉工具链 riscv-gnu-toolchain

文章大纲

更新:2023/6/26

1. 预置条件

参考 RISC-V 工具链官方 README 说明,因为这里演示在 Ubuntu 上制作,所以采用 apt 安装如下软件:

$ sudo apt-get install autoconf automake autotools-dev curl python3 libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev

2. 下载源码

注意下面的描述是参考的 RISC-V 工具链官方 README 说明,如果你本地因为不可描述的原因无法顺利地下载相关仓库,可以参考本文附录 - "采用国内 mirror 下载相关仓库"。p.s. 目前感觉这些依赖的仓库基本上国内本地还是可以访问的,所以一般不需要太费周折。

假设我们的工作目录所在的路径为 $WS。执行如下命令下载 RISC-V 基金会维护的构建脚本仓库,下载完成后进入 clone 的仓库目录 riscv-gnu-toolchain

$ cd $WS
$ git clone git@github.com:riscv-collab/riscv-gnu-toolchain.git
$ cd riscv-gnu-toolchain

注意上面 clone 的仓库,我们称其为构建脚本仓库,其并不包含 gcc 等工具源码,这些源码以 git 的 submodule 的形式作为子仓库的内容发布,所以需要继续更新子仓库。注意这里我们首先删除了部分子仓库,一来因为这些子仓库,譬如 qemu 完整下载太大;二来这些子仓库对 toolchain 的编译本身来说其实并不需要。

$ git rm qemu
$ git rm spike
$ git rm pk

然后就可以下载子仓库了,运行如下命令,注意加上 --progress,方便查看进度,因为下载内容较多,好几个 G,需要等待一会时间。

$ git submodule update --init --recursive --progress

3. 编译 RISC-V 的交叉工具链

编译时为尽量不污染 riscv-gnu-toolchain 目录,我们退出 riscv-gnu-toolchain,在 riscv-gnu-toolchain 外面新建一个同级的 build 目录,同时将编译完的工具链安装到同级的 install 目录下。我们这里编一个 Linux cross-compiler,如果要编译其他的 cross-compiler,请自行阅读 RISC-V 工具链官方 README 说明

$ cd $WS
$ mkdir build && cd build
$ ../riscv-gnu-toolchain/configure --prefix=$WS/install 
$ make linux -j $(nproc)

测试 toolchain 是否安装成功。后面也可以导出 toolchain 的安装路径,譬如将 export PATH="$PATH:$WS/install/bin" 写入 .bashrc 文件,以后就可以不用每次输入完整路径了。

$ $WS/install/bin/riscv64-unknown-linux-gnu-gcc -v

出现类似如下输出表示工具链编译安装正常。

Using built-in specs.
COLLECT_GCC=../install/bin/riscv64-unknown-linux-gnu-gcc
COLLECT_LTO_WRAPPER=/home/u/ws/test-gcc/install/libexec/gcc/riscv64-unknown-linux-gnu/11.1.0/lto-wrapper
Target: riscv64-unknown-linux-gnu
Configured with: /home/u/ws/test-gcc/build/../riscv-gnu-toolchain/riscv-gcc/configure --target=riscv64-unknown-linux-gnu --prefix=/home/u/ws/test-gcc/install --with-sysroot=/home/u/ws/test-gcc/install/sysroot --with-pkgversion=g5964b5cd727 --with-system-zlib --enable-shared --enable-tls --enable-languages=c,c++,fortran --disable-libmudflap --disable-libssp --disable-libquadmath --disable-libsanitizer --disable-nls --disable-bootstrap --src=../../riscv-gnu-toolchain/riscv-gcc --disable-multilib --with-abi=lp64d --with-arch=rv64imafdc --with-tune=rocket --with-isa-spec=2.2 'CFLAGS_FOR_TARGET=-O2   -mcmodel=medlow' 'CXXFLAGS_FOR_TARGET=-O2   -mcmodel=medlow'
Thread model: posix
Supported LTO compression algorithms: zlib
gcc version 11.1.0 (g5964b5cd727) 

编译一个简单的 hello 程序,这里采用静态链接,方便测试。

$ cat hello.c 
#include <stdio.h>

int main()
{
	printf("hello!\n");
	return 0;
}
$ $WS/install/bin/riscv64-unknown-linux-gnu-gcc -static hello.c -o a.out

看一下生成的 a.out,出现 "RISC-V" 字样,说明交叉编译成功。

$ file a.out
a.out: ELF 64-bit LSB executable, UCB RISC-V, version 1 (SYSV), statically linked, for GNU/Linux 4.15.0, with debug_info, not stripped

用 qemu 简单测试一下,打印 "hello!" 说明成功。这个 qemu 可以自己安装或者自己构建,这里就不赘述了。

$ qemu-riscv64 a.out
hello!

4. 编译其他版本的 RISC-V GCC

目前上面构建出来的 GCC 版本,会有默认的版本,所有的子仓库源和版本都配置在是 .gitmodules 这个文件中。以我目前使用的为例:

$ cd riscv-gnu-toolchain
$ cat .gitmodules 
[submodule "binutils"]
	path = binutils
	url = https://sourceware.org/git/binutils-gdb.git
	branch = binutils-2_40-branch
[submodule "gcc"]
	path = gcc
	url = https://gcc.gnu.org/git/gcc.git
	branch = releases/gcc-12
[submodule "glibc"]
	path = glibc
	url = https://sourceware.org/git/glibc.git
[submodule "dejagnu"]
	path = dejagnu
	url = https://git.savannah.gnu.org/git/dejagnu.git
	branch = dejagnu-1.6.3
[submodule "newlib"]
	path = newlib
	url = https://sourceware.org/git/newlib-cygwin.git
	branch = master
[submodule "gdb"]
	path = gdb
	url = https://sourceware.org/git/binutils-gdb.git
	branch = gdb-12-branch
[submodule "musl"]
	path = musl
	url = https://git.musl-libc.org/git/musl
	branch = master
[submodule "spike"]
	path = spike
	url = https://github.com/riscv-software-src/riscv-isa-sim.git
	branch = master
[submodule "pk"]
	path = pk
	url = https://github.com/riscv-software-src/riscv-pk.git
	branch = master
[submodule "llvm"]
	path = llvm
	url = https://github.com/llvm/llvm-project.git
	branch = release/15.x

如果我们想构建其他版本的 GCC 可以在执行 git submodule update 之前先修改一下 .gitmodules 这个文件,把 [submodule "gcc"] 下的 branch 内容修改为自己想要的分支,譬如: branch = releases/gcc-13,然后再执行 git submodule update 即可。

但需要注意的是,上面的修改只能是 branch,不支持在 "branch =" 后跟 commit id 或者 tag。

所以如果要切换到 tag 上,还有一种方法是在已经 git submodule update 过后,自己进入 riscv-gnu-toolchain 下的 gcc 子目录自己同步。如果觉得 gnu 的官方源比较慢,也可以尝试换成国内的 mirror,譬如: https://mirrors.tuna.tsinghua.edu.cn/git/gcc.git

$ cd $WS/riscv-gnu-toolchain/riscv-gcc
$ git remote add tsinghua https://mirrors.tuna.tsinghua.edu.cn/git/gcc.git
$ git fetch --all

然后就可以切换到你想要构建的版本上去了,正式发布版本都有对应的 tag,譬如如下切换:

$ git checkout releases/gcc-13.1.0

其他的子仓库一般不用动,gcc 可能依赖比较紧密的 c 库或者 binutils 最好取比较新的。具体构建 gcc 的依赖参考 GCC 官方文档 "Prerequisites for GCC"

后面的构建操作都是类似的,就不赘述了。

5. 编译支持 rvv 的 gcc

在章节 3 中我们构建的 gcc 默认是 RV64GC 的,如果我们要支持其他的扩展,譬如 V 扩展可以参考如下方法:

确保 gcc 版本在 13 以上。具体方法参考章节 4.

configure 时带上额外的参数

$ cd $WS
$ mkdir build && cd build
$ ../riscv-gnu-toolchain/configure --prefix=$WS/install --with-arch=rv64gcv --with-abi=lp64d
$ make linux -j $(nproc)

编写一个简单的 rvv 测试程序:

$ cat hello.S
.data
.align 3
string:
        .ascii "hello RVV!\n"

.text
.align 2
.globl main
main:
        addi    sp,sp,-16

        vsetivli t0, 10, e8
        la a1, string
        vle8.v v1, (a1)

        # print the string
        la a0, string
        sd ra,8(sp)
        call printf
        ld ra,8(sp)

        li a0, 0
        addi    sp,sp,16
        ret

用新制作的 gcc 编译:

$ riscv64-unknown-linux-gnu-gcc -march=rv64gcv hello.S -o hello

使用 qemu 测试,记得带上 -cpu rv64,v=true,vlen=256,vext_spec=v1.0, 否则默认不支持 rvv。

$ qemu-riscv64 -cpu rv64,v=true,vlen=256,vext_spec=v1.0 -L $WS/install/sysroot hello
hello RVV!

6. 附录 - 采用国内 mirror 下载相关仓库

注:目前国内网络似乎不用 mirror 也可以,所以本章节不再维护更新。

$ git clone https://gitee.com/mirrors/riscv-gnu-toolchain
$ cd riscv-gnu-toolchain

同样地删除一些子仓库,一般情况下我们制作 gcc 工具链只需要保留几个必要的仓库,所以这里我除了删除了 qemu 还删除了 musl、pk 和 spike

$ git rm qemu
$ git rm musl
$ git rm spike
$ git rm pk

然后还要修改一下 riscv-gnu-toolchain 目录下的 .gitmodules 这个文件,因为默认下载下来的仓库里的 submodule 所指向的 URL 下载速度会很慢,所以我们把它们替换为国内的一些 mirror URL,我这里简单显示一下 diff

@@ -1,23 +1,23 @@
 [submodule "riscv-binutils"]
        path = riscv-binutils
-       url = https://github.com/riscv-collab/riscv-binutils-gdb.git
-       branch = riscv-binutils-2.38
+       url = https://gitee.com/mirrors/riscv-binutils-gdb.git
+       branch = riscv-binutils-2.36.1
 [submodule "riscv-gcc"]
        path = riscv-gcc
-       url = https://github.com/riscv-collab/riscv-gcc.git
+       url = https://gitee.com/mirrors/riscv-gcc.git
        branch = riscv-gcc-10.2.0
-[submodule "glibc"]
-       path = glibc
-       url = git://sourceware.org/git/glibc.git
+[submodule "riscv-glibc"]
+       path = riscv-glibc
+       url = https://mirrors.tuna.tsinghua.edu.cn/git/glibc.git
 [submodule "riscv-dejagnu"]
        path = riscv-dejagnu
-       url = https://github.com/riscv-collab/riscv-dejagnu.git
+       url = https://gitee.com/mirrors/riscv-dejagnu.git
        branch = riscv-dejagnu-1.6
-[submodule "newlib"]
-       path = newlib
-       url = git://sourceware.org/git/newlib-cygwin.git
+[submodule "riscv-newlib"]
+       path = riscv-newlib
+       url = https://gitee.com/mirrors/riscv-newlib.git
        branch = master
 [submodule "riscv-gdb"]
        path = riscv-gdb
-       url = https://github.com/riscv-collab/riscv-binutils-gdb.git
+       url = https://gitee.com/mirrors/riscv-binutils-gdb.git
        branch = fsf-gdb-10.1-with-sim

然后就可以同步了,其他操作同上。

1
https://gitee.com/aosp-riscv/working-group.git
git@gitee.com:aosp-riscv/working-group.git
aosp-riscv
working-group
working-group
master

Search

53164aa7 5694891 3bd8fe86 5694891