- [原始內容請參閱此處](https://rissun-mu-yasorganization.gitbook.io/rissun-mu-yasorganizartion/riscvcpu-shi-zuo-dao-lun/vscode-zheng-he-huan-jing-pei-zhi)
當 RISC-V 工具鏈配置好後,很自然會開始覺得如果能夠直接在 Vscode 執行就好了,確實這樣就能夠創造類似 IDE 的環境每次都能夠快速編譯和輸出結果到終端,而不必每次都要打一堆指令去編譯和執行。
## 安裝 Vscode 在 Ubuntu
Ubuntu 用戶可以在 App Center 搜索 找到 Vscode,只要直接安裝就能使用。
開啟 Vscode ,有了前面一篇的經驗我們大致知道,我們應該先安裝 C/C++ 的語法插件 以及 RISC-V 的語法插件,至於插件的選擇基本上沒有硬性規定,功能也大同小異,只要選自己喜歡的就好了,個人是配置了以下這幾個:
到這裡基本上就完成了 Vscode 的基本安裝了。
配置自動化編譯腳本基於 bash shell
有鑑於前一篇,我們已經非常熟悉在 bash 的編譯操作,所以我們優先配置腳本
- build_cpp.sh
- build_c.sh
- build_as.sh
以開啟自動化編譯之路。build_cpp.sh
基本上就是前一篇的流程加上一些錯誤判斷的機制而已
```bash=1
#!/bin/bash
# 輸入欲編譯之檔案名稱
echo "請輸入要編譯的檔案名稱:"
read filename
# 檢查是否存在欲編譯檔案
if [[ ! -f "$filename.cpp" ]];then
echo "錯誤:找不到檔案 $filename.cpp"
exit 1
fi
# 編譯
echo "正在為你的程序編譯..."
riscv32-unknown-elf-g++ -g -o "$filename.elf" "$filename.cpp"
# 檢查編譯是否成功
if [[ $? -ne 0 ]]; then
echo "編譯失敗,請檢查程式碼。"
exit 1
fi
# 執行
echo "即將為你執行程序.."
qemu-riscv32 "$filename.elf"
```
然後,一樣拿前一篇的測試程式碼來測試
首先,第一次執行 會需要給予該腳本 執行權限所以
```bash
$ chmod +x build_cpp.sh
```
然後,開始執行編譯程序
```bash
$ ./build_cpp.sh
請輸入要編譯的檔案名稱:
test ;
正在為你的程序編譯...
即將為你執行程序..
Hello, RISC-V!
```
看到正確輸出代表 自動化腳本配置已經完成。
build_c.sh 由於內容大同小異,直接複製前一份修改即可
```bash
$ cp build_cpp.sh build_c.sh
```
然後,開啟該檔案修正如下:
```bash=1
#!/bin/bash
# 輸入欲編譯之檔案名稱
echo "請輸入要編譯的檔案名稱:"
read filename
# 檢查是否存在欲編譯檔案
if [[ ! -f "$filename.c" ]];then
echo "錯誤:找不到檔案 $filename.c"
exit 1
fi
# 編譯
echo "正在為你的程序編譯..."
riscv32-unknown-elf-gcc -g -o "$filename.elf" "$filename.c"
# 檢查編譯是否成功
if [[ $? -ne 0 ]]; then
echo "編譯失敗,請檢查程式碼。"
exit 1
fi
# 執行
echo "即將為你執行程序.."
qemu-riscv32 "$filename.elf"
```
接著一樣利用 test.c 測試程式碼
```bash
$ ./build_c.sh
請輸入要編譯的檔案名稱:
test ;
正在為你的程序編譯...
即將為你執行程序..
Hello, RISC-V!
```
完成後,就可以繼續處理組合語言的編譯了build_as.sh
雖然差異最大的一個,不過主要結構仍然大同小異,
所以直接複製前一個檔案即可
```bash
$ cp build_c.sh build_as.sh
```
然後,依據前一篇的邏輯修改
```bash=1
#!/bin/bash
# 輸入欲編譯之檔案名稱
echo "請輸入要編譯的檔案名稱:"
read filename
# 檢查是否存在欲編譯檔案
if [[ ! -f "$filename.as" ]];then
echo "錯誤:找不到檔案 $filename.as"
exit 1
fi
# 編譯
echo "正在為你的程序編譯..."
riscv32-unknown-elf-as -g -o "$filename.o" "$filename.as"
riscv32-unknown-elf-ld -g -o "$filename.elf" "$filename.o"
# 檢查編譯是否成功
if [[ $? -ne 0 ]]; then
echo "編譯失敗,請檢查程式碼。"
exit 1
fi
# 執行
echo "即將為你執行程序.."
qemu-riscv32 "$filename.elf"
```
同樣的來測試看看 test.as 能不能作用,
```bash
$ ./build_as.sh
請輸入要編譯的檔案名稱:
test
正在為你的程序編譯...
即將為你執行程序..
Hello, RISC-V!
```
同樣順利執行後,我們可以開始思考如何把這些腳本配置到 Vscode 了,原因是雖然目前確實可以顯著簡少我們使用指令的數量,但是仍然和我們期待寫程式碼的同時能夠偵錯和獲取結果存在差距,所以必須讓它進入到 Vscode 才能解決這個問題,並達成我們的目標!
Vscode 自動化配置
要配置 Vscode 環境首先必須要先擁有一個能夠專注讓,Vscode 運作的環境具體作法最簡單就是直接新增一個乾淨的資料夾
```bash=1
$ cd ~/Desktop
$ mkdir test
$ cd test
```
由於 Vscode 的編譯運作仰賴 .vscode 的配置,但是這也意味著當一個空間包含多個語言時候,可能環境會變得相當複雜管理,所以簡單起見我們至少在新增2個工做環境分別給予 C/C++, Asm
由於事實上,g++ 可以同時處理 C/C++ 因此我們可以直接都使用它來處理就好,這樣只需要2個工作區域。
```bash
$ mkdir test_cpp
$ mkdir test_asm
```
配置 test_cpp
將剛剛多次使用過得 test.c,test.cpp 放入此資料夾,並且在 Vscode 開啟這個資料夾
具體應該如下:
Ctrl + Shift + P 開啟命令面板,輸入 Tasks: Configure Task,然後選擇 "Create tasks.json file from template"。
得到一個類似這樣的範本:
理想上的配置流程應該是,執行初期要確保環境是沒有過去的執行檔,否則可能造成潛在的誤會和錯誤,所以應該第一步驟為清除過去的 .elf ,第二步驟是開始串接剛剛配置的 build_cpp.sh
具體實現是如下:
```json=1
{
"version": "2.0.0",
"tasks": [
{
"label": "Clean",
"type": "shell",
"command": "rm",
"args": [
"-f",
"${fileDirname}/${fileBasenameNoExtension}.elf",
"${fileDirname}/${fileBasenameNoExtension}.o"
],
"presentation": {
"reveal": "always",
"clear": true
},
"group": "build",
"detail": "清除先前的編譯檔案"
},
{
"label": "Build with build_cpp.sh",
"type": "shell",
"command": "${fileDirname}/build_cpp.sh",
"args": [],
"problemMatcher": [],
"presentation": {
"reveal": "always",
"clear": false
},
"group": "build",
"dependsOn": "Clean",
"dependsOrder": "sequence",
"detail": "使用 build_cpp.sh 自動化編譯流程"
},
{
"label": "Build and Run (C++)",
"dependsOn": "Build with build_cpp.sh",
"dependsOrder": "sequence",
"group": "build",
"problemMatcher": []
},
{
"type": "cppbuild",
"label": "C/C++: g++ build active file",
"command": "/usr/bin/g++",
"args": [
"-fdiagnostics-color=always",
"-g",
"${file}",
"-o",
"${fileDirname}/${fileBasenameNoExtension}"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "Task generated by Debugger."
}
]
}
```
接著打開 C/C++ 的檔案,按下 Ctrl + F5 理論上可以成功
如下:
到這裡基本上已經完成 C/C++ 在 Vscode 基本的環境整合
配置 Asm 整合環境
有了以上經驗,整合 Asm 理論上不成問題了,直接進入到 test_asm,
同樣做好 .vscode 配置,然後開啟 tasks.json 配置:
事實上,與前者同樣大同小異,可以直接修改前者就好了,但是要留意的是,在 Vscode .as 不會被視為可用的所以必須要 修改 build_as.sh:
``` bash=1
#!/bin/bash
# 輸入欲編譯之檔案名稱
echo "請輸入要編譯的檔案名稱:"
read filename
# 檢查是否存在欲編譯檔案
if [[ ! -f "$filename.s" ]];then
echo "錯誤:找不到檔案 $filename.s"
exit 1
fi
# 編譯
echo "正在為你的程序編譯..."
riscv32-unknown-elf-as -g -o "$filename.o" "$filename.s"
riscv32-unknown-elf-ld -g -o "$filename.elf" "$filename.o"
# 檢查編譯是否成功
if [[ $? -ne 0 ]]; then
echo "編譯失敗,請檢查程式碼。"
exit 1
fi
# 執行
echo "即將為你執行程序.."
qemu-riscv32 "$filename.elf"
```
然後,在Vscode 同樣建立一個 test.s 內容,因為其內容和 test.as 相同所以可以直接
```bash
$ cp test.as test.s
```
接著配置任務
```json=1
{
"version": "2.0.0",
"tasks": [
{
"label": "Clean (ASM)",
"type": "shell",
"command": "rm",
"args": [
"-f",
"${fileDirname}/${fileBasenameNoExtension}.elf",
"${fileDirname}/${fileBasenameNoExtension}.o"
],
"presentation": {
"reveal": "always",
"clear": true
},
"group": "build",
"detail": "清除組合語言的舊編譯檔"
},
{
"label": "Build with build_as.sh",
"type": "shell",
"command": "${fileDirname}/build_as.sh",
"args": [
"${fileBasenameNoExtension}" // 傳遞檔案名稱作為引數
],
"problemMatcher": [],
"presentation": {
"reveal": "always",
"clear": false
},
"group": "build",
"dependsOn": "Clean (ASM)",
"dependsOrder": "sequence",
"detail": "使用 build_as.sh 編譯與執行組合語言程式"
},
{
"label": "Build and Run (ASM)",
"dependsOn": "Build with build_as.sh",
"dependsOrder": "sequence",
"group": {
"kind": "build",
"isDefault": false
},
"problemMatcher": []
}
]
}
```
和前者不同,由於組合語言更為底層,經過多次測試後,覺得還是只能麻煩一點就是每次要編譯使用 Ctrl+Shift+B ,跑出編譯選單,
選擇最下面的選項 Build and Run, 接著會要求輸入欲編譯的檔案,
輸入當前檔案名稱即可
得到編譯結果
雖然組合語言部份沒有辦法做到更簡化,不過和原始的相比目前已經可以實現全程在 Vscode 作業了,也確實免除了大多數的指令,總之到目前為止已經完成了編譯上在 Vscode 的整合。