Building Toolchain for RISC-V on macOS

As a part of investigating the CH32V series RISC-V MCU development environment on Mac, I tried to build the cross-toolchain for RISC-V by using Crosstool-NG on my Mac basically in the same way I did before on the Ubuntu 20.04. I used the same MacBook Pro  (intel, 13inch, 2020), and the OS version was macOS Monterey (Version 12.3.1).

To build the Crosstool-NG, I added additional Homebrew packages at first.

brew install bash texinfo libtool libmpc zlib gawk bison flex gperf patchutils help2man ncurses dtc expat gnu-sed binutils xz curl wget python@3.8

I built and installed the Crosstool-NG as follows.

export PATH="/usr/local/opt/python@3.8/bin:/usr/local/opt/binutils/bin:/usr/local/opt/ncurses/bin:$PATH"
export LDFLAGS="-L/usr/local/opt/python@3.8/lib -L/usr/local/opt/ncurses/lib"
export CPPFLAGS="-I/usr/local/opt/ncurses/include"
export PKG_CONFIG_PATH="/usr/local/opt/python@3.8/lib/pkgconfig"

git clone https://github.com/crosstool-ng/crosstool-ng
cd crosstool-ng
./bootstrap
./configure
make
sudo make install
sudo ct-ng update-samples

As seen in the above procedure, the setting of the environment variables for the ncurses was necessary for building the Crosstool-NG. And also, without specifying the environment variables for the python 3.8, which the Homebrew installed, I could build the Crosstool-NG itself. However, the Crosstool-NG without the above python settings failed to build the GCC 12.1.0 by a Python-related error.

Unfortunately, it also turned out that the Crosstool-NG requires a case-sensitive file system to build the toolchain (There is a description about this on the official site). To prepare the case-sensitive file system, this time, I created a disk image formatted with the case-sensitive file system using the hdiutil command and mounted the disk image under my home directory by the hdid command and the mount command as follows.

cd ~
hdiutil create -type SPARSE -fs 'Case-sensitive Journaled HFS+' -size 32g -volname csfs csfs

mkdir csfs
hdid -nomount csfs.sparseimage
mount -t hfs /dev/disk2s2 csfs

The device filename of the disk image (/dev/disk2s2) might have a different name under a different environment. The command hdid outputs the device filename of the specified disk image.

After mounting the created disk image under the ~/csfs directory, I built the cross-toolchain using the Crosstool-NG as follows.

cd csfs
mkdir build
mkdir src
cd build

ct-ng riscv32-unknown-elf
ct-ng menuconfig

For the ct-ng menuconfig command, I changed the following options from the default.

  • In the Path and misc options menu, I changed the Local tar balls directory setting from ${HOME}/src to ${HOME}/csfs/src and inserted /csfs between ${HOME} and /x-tools in the Prefix directory setting.
  • In the Target options menu, I enabled the Build a multilib toolchain.
  • In the C-library menu, I selected the newlib as the C library.
  • In the Companion libraries menu, I selected the newlib-nano and enabled the Additionally install newlib-nano libs into TARGET dir option for the newlib-nano.
  • In the Debug facilities menu, I enabled the gdb menu item and disabled the python scripting option inside the gdb menu item.

After saving the changes to the .config file, I initiated the toolchain build by the following command.

ct-ng build

The toolchain build took about 50mins with my Mac, and I finally got the working toolchain binaries under ~/csfs/x-tools/riscv32-unknown-elf.