Go to file
Shao-Ce SUN 7e2788c51c
增加贡献者 cyk2018
2024-04-22 16:12:35 +08:00
.vscode Update launch.json 2022-08-03 22:07:22 +08:00
ppt 增加PLCT Open Day的ppt 2022-12-15 00:48:47 +08:00
README.md Update README.md for cross-compilation (#19) 2024-04-22 16:11:05 +08:00
contributors.md 增加贡献者 cyk2018 2024-04-22 16:12:35 +08:00
install-riscv-1.sh 更新文档 2022-07-30 22:36:44 +08:00
install-riscv-2.sh Update install-riscv-2.sh (#16) 2022-10-13 21:02:48 +08:00
jump.sh 更新jump注释 2022-07-29 19:29:11 +08:00
术语表.md 增加术语 2022-09-22 10:11:37 +08:00

README.md

rvcc-course

这里是RVCC课程的相关仓库,存放了课程相关的材料。

欢迎利用PR来对本仓库进行补充。


  • 【1】 这个课程都需要准备什么东西?
  • 【2】 如何安装RISCV的实验环境
    • 方式一推荐解压预先编译好的RISCV环境基于Ubuntu 20.04
    • 方式二源代码编译RISCV环境较难
    • 方式三使用配置好的Docker环境
  • 【3】 如何对RVCC中的项目使用make test进行测试
    • 第1课第22课
    • 第23课第44课
    • 第45课第154课
    • 第155课第178课
    • 第179课第361课
  • 【4】 跳转脚本(可选)

【1】 这个课程都需要准备什么东西?

  1. Linux的运行环境推荐Ubuntu 20.04。
  2. RISC-V的实验环境需要编译器和模拟器如何安装参考问题【2】。
  3. 下载RVCC的仓库git clone https://github.com/sunshaoce/rvcc

【2】 如何安装RISCV的实验环境

三种方式自由选择新手推荐方式1.

方式一推荐解压预先编译好的RISCV环境基于Ubuntu 20.04

运行仓库的install-riscv-1.sh即可。

方式二源代码编译RISCV环境较难

这里我们编译出编译器gcc和模拟器qemu。使用本课程的install-riscv-2.sh脚本(请勿直接运行),使用方法参考视频:RISCV环境快速配置

方式三使用配置好的Docker环境

详情可以参考:https://github.com/ksco/rvcc-env-docker

【3】 如何对RVCC中的项目使用make test进行测试

首先,你需要找到你RISCV实验环境的路径,方式一、二的路径为:~/riscv

其次,你需要将test.shMakefile中的下面几行代码选择为你对应的编译器和模拟器例子默认为gcc和qemu如下方所示。

最后运行RISCV=~/riscv make test,注意这里的~/riscv必须是你RISCV实验环境的路径

第1课第22课

修改前:

  # 运行程序传入期待值将生成结果写入tmp.s汇编文件。
  # 如果运行不成功则会执行exit退出。成功时会短路exit操作
  ./rvcc "$input" > tmp.s || exit
  # 编译rvcc产生的汇编文件
  clang -o tmp tmp.s
  # $RISCV/bin/riscv64-unknown-linux-gnu-gcc -static -o tmp tmp.s

  # 运行生成出来目标文件
  ./tmp
  # $RISCV/bin/qemu-riscv64 -L $RISCV/sysroot ./tmp
  # $RISCV/bin/spike --isa=rv64gc $RISCV/riscv64-unknown-linux-gnu/bin/pk ./tmp

修改后:

  # 运行程序传入期待值将生成结果写入tmp.s汇编文件。
  # 如果运行不成功则会执行exit退出。成功时会短路exit操作
  ./rvcc "$input" > tmp.s || exit
  # 编译rvcc产生的汇编文件
  # clang -o tmp tmp.s
  $RISCV/bin/riscv64-unknown-linux-gnu-gcc -static -o tmp tmp.s

  # 运行生成出来目标文件
  # ./tmp
  $RISCV/bin/qemu-riscv64 -L $RISCV/sysroot ./tmp
  # $RISCV/bin/spike --isa=rv64gc $RISCV/riscv64-unknown-linux-gnu/bin/pk ./tmp

第23课第44课

第1课第22课的基础上,再将

# 将下列代码编译为tmp2.o"-xc"强制以c语言进行编译
# cat <<EOF | $RISCV/bin/riscv64-unknown-linux-gnu-gcc -xc -c -o tmp2.o -
cat <<EOF | clang -xc -c -o tmp2.o -
int ret3() { return 3; }
int ret5() { return 5; }
EOF

改为(注意此处删去了一行,不是注释掉

# 将下列代码编译为tmp2.o"-xc"强制以c语言进行编译
cat <<EOF | $RISCV/bin/riscv64-unknown-linux-gnu-gcc -xc -c -o tmp2.o -
int ret3() { return 3; }
int ret5() { return 5; }
EOF

第45课第154课

这个时候已经没有了test.sh,我们直接修改Makefile

# 测试标签,运行测试
test/%.exe: rvcc test/%.c
	$(CC) -o- -E -P -C test/$*.c | ./rvcc -o test/$*.s -
#	$(RISCV)/bin/riscv64-unknown-linux-gnu-gcc -o- -E -P -C test/$*.c | ./rvcc -o test/$*.s -
	$(CC) -static -o $@ test/$*.s -xc test/common
#	$(RISCV)/bin/riscv64-unknown-linux-gnu-gcc -static -o $@ test/$*.s -xc test/common

test: $(TESTS)
	for i in $^; do echo $$i; ./$$i || exit 1; echo; done
#	for i in $^; do echo $$i; $(RISCV)/bin/qemu-riscv64 -L $(RISCV)/sysroot ./$$i || exit 1; echo; done
#	for i in $^; do echo $$i; $(RISCV)/bin/spike --isa=rv64gc $(RISCV)/riscv64-unknown-linux-gnu/bin/pk ./$$i || exit 1; echo; done
	test/driver.sh

改为(注意需要删去几行,而非注释掉

# 测试标签,运行测试
test/%.exe: rvcc test/%.c
	$(RISCV)/bin/riscv64-unknown-linux-gnu-gcc -o- -E -P -C test/$*.c | ./rvcc -o test/$*.s -
	$(RISCV)/bin/riscv64-unknown-linux-gnu-gcc -static -o $@ test/$*.s -xc test/common

test: $(TESTS)
	for i in $^; do echo $$i; $(RISCV)/bin/qemu-riscv64 -L $(RISCV)/sysroot ./$$i || exit 1; echo; done
#	for i in $^; do echo $$i; $(RISCV)/bin/spike --isa=rv64gc $(RISCV)/riscv64-unknown-linux-gnu/bin/pk ./$$i || exit 1; echo; done
	test/driver.sh

第155课第178课

第45课第154课的基础上,修改main.c进行交叉编译测试。

// 【注意】
// 如果是交叉编译,请把这个路径改为$RISCV对应的路径
// 注意 ~ 应替换为具体的 /home/用户名 的路径
static char *RVPath = "";

改为RISCV实验环境的路径,例如"~/riscv",同时~应替换为你的"/home/用户名"

// 【注意】
// 如果是交叉编译,请把这个路径改为$RISCV对应的路径
// 注意 ~ 应替换为具体的 /home/用户名 的路径
static char *RVPath = "/home/用户名/riscv";

第179课第361课

和前面第155课第178课类似,但是简化掉了之前的这个操作。

# 测试标签,运行测试
test/%.exe: rvcc test/%.c
	$(CC) -o- -E -P -C test/$*.c | ./rvcc -o test/$*.s -
#	$(RISCV)/bin/riscv64-unknown-linux-gnu-gcc -o- -E -P -C test/$*.c | ./rvcc -o test/$*.s -

【4】 跳转脚本(可选)

感谢 @daquexian。

用法是把它复制到 rvcc 项目目录之后:

./jump.sh n 跳转到下一节课程 commit
./jump.sh p 跳转到上一节课程的 commit
./jump.sh <number> 跳转到第 number 节课程的 commit

不想污染 rvcc 目录的话也可以不复制,只要在 rvcc 目录下用正确的脚本路径运行就行。

【5】交叉编译配置

对于交叉编译方案需要配置Makefile才能正确执行测试:

  1. 在main.c中修改RVPath
// 【注意】
// 如果是交叉编译,请把这个路径改为$RISCV对应的路径
// 注意 ~ 应替换为具体的 /home/用户名 的路径
static char *RVPath = "";

改为RISCV实验环境的路径,例如"~/riscv",同时~应替换为你的"/home/用户名"可以使用pwd命令查看

// 【注意】
// 如果是交叉编译,请把这个路径改为$RISCV对应的路径
// 注意 ~ 应替换为具体的 /home/用户名 的路径
static char *RVPath = "/home/用户名/riscv";
  1. 配置交叉编译环境

在 test/%.exe: rvcc test/%.c 部分和 test: $(TESTS) 部分的编译命令均改为交叉编译命令。

# 测试标签,运行测试
test/%.exe: rvcc test/%.c
	./rvcc -Iinclude -Itest -I$(RISCV)/sysroot/usr/include -c -o test/$*.o test/$*.c
	$(CC) -pthread -o $@ test/$*.o -xc test/common
#	$(RISCV)/bin/riscv64-unknown-linux-gnu-gcc -pthread -static -o $@ test/$*.o -xc test/common

test: $(TESTS)
	for i in $^; do echo $$i; ./$$i || exit 1; echo; done
#	for i in $^; do echo $$i; $(RISCV)/bin/qemu-riscv64 -L $(RISCV)/sysroot ./$$i || exit 1; echo; done
#	for i in $^; do echo $$i; $(RISCV)/bin/spike --isa=rv64gc $(RISCV)/riscv64-unknown-linux-gnu/bin/pk ./$$i || exit 1; echo; done
	test/driver.sh ./rvcc

改为

# 测试标签,运行测试
test/%.exe: rvcc test/%.c
	./rvcc -Iinclude -Itest -I$(RISCV)/sysroot/usr/include -c -o test/$*.o test/$*.c
#	$(CC) -pthread -o $@ test/$*.o -xc test/common
	$(RISCV)/bin/riscv64-unknown-linux-gnu-gcc -pthread -static -o $@ test/$*.o -xc test/common

test: $(TESTS)
# 	for i in $^; do echo $$i; ./$$i || exit 1; echo; done
	for i in $^; do echo $$i; $(RISCV)/bin/qemu-riscv64 -L $(RISCV)/sysroot ./$$i || exit 1; echo; done
#	for i in $^; do echo $$i; $(RISCV)/bin/spike --isa=rv64gc $(RISCV)/riscv64-unknown-linux-gnu/bin/pk ./$$i || exit 1; echo; done
	test/driver.sh ./rvcc

注意:如果使用Spike请开启第三行代码。