macOSでRISC-Vのコンパイル環境・実行環境を整える（2024年2月現在）

こんにちは｜こんばんは。カエルのアイコンで活動しております @kyamaz :frog: です。

# はじめに
私:frog:は、2018-2019年頃に『[RISC-Vの量子計算拡張](https://qiita.com/kyamaz/items/a0e468d78547ee466318)』にある取り組みをしておりました。それから５年以上経って、RISC-V界隈の状況も変わってきております。Githubのリポジトリの構成やコンパイルの環境も変化しております。本稿では、そのアップデートとして2024年2月現在で、macOSでRISC-Vのコンパイル環境・実行環境を整えることを主題にて書いて参ります。

macOSで homebrew を使った方法は、下記の@zacky1972さんのエントリーにある通り `brew install riscv64-elf-gcc`で整います。ただ本稿では、この簡単な方法ではなく、コンパイル環境をビルドして整えることを目指します。

https://qiita.com/zacky1972/items/0cbfdf4e400e0205aa7b

更に、実行環境も下記の@zacky1972さんのエントリーで整えられますが、こちらもソースコードからビルドして整えてみましょう。

https://qiita.com/zacky1972/items/6d433bdbef737d1e300f

ソースコードからビルドして整える目的ですが、ここで整えたコンパイル環境・実行環境を使って、RISC-V関連のソースコードを変更して遊べるようにしたいからです。前出の『RISC-Vの量子計算拡張』のようなことを試してみようとすると、自前でビルドする環境が必要とります。

お手元の環境によっては状況が異なる可能性もあります。本稿を記載するために動作確認した環境を次に掲載しておきます。

**本稿の環境**
- macOS: Sonoma 14.2.1 (chip: Apple M1)
- LLVM: Homebrew LLVM version 17.0.6
- Xcode: Apple clang version 15.0.0 (clang-1500.1.0.2.5)
  （PATH環境変数により、Homebrew LLVMを先にしてあります）
- Python: 3.12.1 （anyenvにて設定）

## RISC-Vのコンパイル環境を整える

適当なワーキングディレクトリ（例；`~/work`）にソースコードをGithubからcloneして、ビルドしていきましょう。まずは、ソースコードを入手します。

```shell-session:
$ cd ~/work
$ git clone https://github.com/riscv/riscv-gnu-toolchain
$ cd riscv-gnu-toolchain
```
入手したら以下の手順を進めましょう。ここで、インストールフォルダは、`/opt/riscv`の下にしたいので、このフォルダは事前に作成（`sudo mkdir -p /opt/riscv`）し、パーミッションも適当に設定しておいてください。
環境変数`RISCV`を設定してください。この環境変数は実行環境を整えた後も使うと便利です（できれば、.zprofile等に設定しておきましょう）。

```shell-session:
$ export RISCV=/opt/riscv
```

### riscv-gnu-tools

OSSでは、プロジェクトフォルダの直下にある`README.md`を読むとビルド方法やインストール方法が記載されています。`README.md`を見ると、おおよその流れが書かれていますので、参考にしながら進めます。

事前準備に記述があるように`brew install gawk gnu-sed gmp mpfr libmpc isl zlib expat texinfo flock`を試します。（pythonは別途環境を整えてありますのでここでは省いてあります。）私は既に全てインストール済みでしたので特に何もしなくてよいです。

`git submodule`は自動的にされるとありますが、次に示すように更新しておきましょう。

```shell-session:
$ git submodule update --remote
```

ビルドのための準備が整いました。ビルドにはその環境に応じたオプショナルがありますが、ここでは`linux`で動作するようなモジュールを作成するためのクロスコンパイルにすることはしないで、スタンドアローンで動作するようにておきます。ここではRV32とRV64の両方のライブラリを作成すること（`--enable-multilib`）にしますが、multilibとllvm（`--enable-llvm`）を同時に指定するとエラーが発生します。llvmはマルチライブラリをサポートしていないので`--enable-multilib`のみ有効にして`configure`した後に`make`します。

```shell-session:
$ ./configure --prefix=$RISCV --enable-multilib
$ make -j$(nproc)
 ```

正常にビルドが終了したら、`/opt/riscv/bin`にコンパイラ`riscv64-unknown-elf-gcc` 等、コンパイル環境としての実行ファイルがインストールされていることを確認してください。

<details><summary>簡単なサンプルプログラム</summary>

```c: hello_world.c
#include <stdlib.h>
#include <stdio.h>
int main(int argc, char **argv){
  printf("test\n");
  exit(0);
}
```
</details>

次のように、このプログラムをコンパイルしてみましょう。特にエラーが出なければ、正常にコンパイル環境が整いました。

```shell-session:
$ $RISCV/bin/riscv64-unknown-elf-gcc -o hello_world hello_world.c
```
この手順で作成した RISC-V 上で動作する実行モジュール hello_world は、この次の実行環境の検証に使います。

## RISC-Vの実行環境を整える

次に実行環境を整えます。上記の`riscv-gnu-tools`の中でシミュレータをビルドすることもできます。ビルドの方法は`make -j$(nproc) build-sim SIM=●●●`です。この`SIM=`の●●●で`qemu` `spike` `gdb`を選択的に指定できます。しかしながら、私の環境（macOS）ではそのままで上手くビルドできませんでした。`SIM=spike`の場合は`Makefile`を修正して、少し工夫するとインストールすることはできます。
本稿では、`riscv-isa-sim`と`riscv-pk`を独立してソースコードを入手してビルドすることで環境を整えることとします。ワーキングディレクトリの下で、それぞれのソースコードを`git clone`して入手します。

```shell-session:
$ cd ~/work
$ git clone https://github.com/riscv-software-src/riscv-isa-sim.git
$ git clone https://github.com/riscv-software-src/riscv-pk.git
```

### riscv-isa-sim

プロジェクトフォルダ直下の`README.md`に従って、ビルドしましょう。

```shell-session:
$ cd ~/work/riscv-isa-sim
$ mkdir build
$ cd build
$ ../configure --prefix=$RISCV --with-boost-regex=boost_regex-mt
$ make -j$(nproc)
$ make install
```

`/opt/riscv/bin`の下に`spike`というコマンド他の実行ファイルがインストールされます。

### riscv-pk

こちらもプロジェクトフォルダ直下の`README.md`に従って、ビルドします。

```shell-session:
$ cd ~/work/riscv-pk
$ mkdir build
$ cd build
$ ../configure --prefix=$RISCV --host=riscv64-unknown-elf --with-arch=rv64gc_zifencei
$ make -j$(nproc)
$ make install
 ```

モジュールは、`/opt/riscv/riscv64-unknown-elf/bin`にインストールされます。`pk` `bbl`というファイルがインストールされていることを確認してください。
最後に、簡単なサンプルプログラム hello_world.c をコンパイルしたモジュールをシミュレータ`spike`で実行して動作させて、実行環境が適切に整っていることを確認しましょう。

 ```shell-session:
$ $RISCV/bin/spike $RISCV/riscv64-unknown-elf/bin/pk hello_world
test
 ```
 無事、"test"と表示されました。

 ## 終わりに
macOSでRISC-Vのコンパイル環境・実行環境を整えました。この環境で、RISC-Vのカスタム命令を用いた拡張を試すことができます。[量子計算拡張『K extension』の提案](https://quantum.siprop.org/risc-v-quantum-extension/)については、またいつか投稿したいと思います。