Coder Social home page Coder Social logo

rvcc-course's Introduction

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,请开启第三行代码。

rvcc-course's People

Contributors

changliuxy avatar cyk2018 avatar daquexian avatar jiangshengdev avatar ksco avatar sunshaoce avatar zchrissirhcz avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

rvcc-course's Issues

parse 函数定义语法存在歧义

第25个commit, 零参数的函数定义中函数语法是这样给出的
// functionDefinition = declspec declarator? ident "(" ")" "{" compoundStmt*
然后declarator的语法要求必须有标识符的
// declarator = "" ident typeSuffix
这样一个函数声明就有两个标识符了
另外functionDefinition 中对declarator 标记了"?",然后function函数实现中, 逻辑中要求必须有declarator
函数实现的语法 应该是 // functionDefinition = declspec declarator"{" compoundStmt*

vscode下断点调试launch.json配置文件

{
    // Use IntelliSense to learn about possible attributes.
    // Hover to view descriptions of existing attributes.
    // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
    "version": "0.2.0",
    "configurations": [
        {
            "type": "cppdbg",
            "request": "launch",
            "name": "Debug",
            "program": "${workspaceFolder}/rvcc",
            "args": [
                "1-8/(2*2)+3*6"
            ],
            "environment": [
                {
                    "name": "config",
                    "value": "Debug"
                }
            ],
            "cwd": "${workspaceFolder}",
            "linux": {
                "MIMode": "gdb",
                "miDebuggerPath": "/usr/bin/gdb"
            },
            "osx": {
                "MIMode": "lldb"
            },
            "windows": {
              "MIMode": "gdb",
              "miDebuggerPath": "C:\\MinGw\\bin\\gdb.exe"
            }
        }
    ]
}

args修改为需要执行的参数

以上配置仅在macOS 12.5下经过测试,请Windows用户自行安装MinGw或使用其他方式

参考文档:https://code.visualstudio.com/docs/cpp/launch-json-reference

rvcc 仓库 CMakeLists.txt 可改进的地方

  1. project(rvcc) 没有写 language,默认的 language 是 C CXX(见 文档LANGUAGES 一节),而这个项目应该只会用到 c 语言,所以可以改为 project(rvcc C)
  2. SET( CMAKE_C_FLAGS "-std=c11 -g -fno-common" ) 有两处可以改进的地方,一个是 set 可以改为小写,和其它地方(projectadd_executable 等)大小写统一,一个是可以重写为 target-based 的 modern cmake 风格:target_compile_options(rvcc PRIVATE -std=c11 -g -fno-common),如果后期 target 变多,逐个 target 设置不方便,可以改为使用 add_compile_options 设置全局的 flags,也比直接设置 CMAKE_C_FLAGS 要更现代一些

44 域处理中的一个疑问

在commit 44 处理代码块域中, rvcc是不支持一个作用域中同名标识符声明的冲突检测的, 比如下列情况可以正常运行

  ASSERT(4, ({ int x=2; int x = 4;{ int x=3; } int y=4; x; }));

我往后看写一些(只看了一点), 没看到这个问题的解决

不过我想这个只需要在当前的scope中遍历下是否声明过就能解决, 所以觉得应该是作者故意这么写的

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.