How to build the Nuclei RISC-V GNU Compiler Toolchain (riscv-gnu-toolchain) on macOS.
Information
The Nuclei RISC-V GNU Compiler Toolchain can be used by the Sipeed Longan Nano development board.
Operating system used
macOS Monterey
Software prerequisites
Homebrew
Procedure
- The official RISC-V GNU Compiler Toolchain source can be found at:
https://github.com/riscv-collab/riscv-gnu-toolchain
The riscv-gnu-toolchain contains:
- The GNU Binutils - a collection of binary tools, such as the GNU linker (ld), The GNU assembler (as), etc.
- gcc compiler
- newlib and glibc libraries
- Linux UAPI headers
- Many SoC manufacturers (SiFive, Nuclei System Technology), uses the official RISC-V GNU Compiler Toolchain source.
These manufacturers modified the official source to make it work for their products.
- The Sipeed Longan Nano development board uses the RISC-V GNU Compiler Toolchain provided by Nuclei System Technology.
Unfortunately the Nuclei RISC-V GNU Compiler Toolchain is only available for Windows and Linux.
See procedure How to build the RISC-V GNU Toolchain for Nuclei RISC-V Processor on Windows and Linux.
Nuclei System Technology has forked the official RISC-V GNU Compiler Toolchain git repository:
https://github.com/riscv-mcu/riscv-gnu-toolchain
- In this tutorial I will demonstrate how to build the RISC-V GNU Toolchain for Nuclei RISC-V Processor on macOS (Monterey).
- First check which shell your Mac is using:
Type: echo $0
If the shell is not bash, change the default shell to bash by running the following command:
Type: chsh -s /bin/bash
- Installing the Mac OSX Command Line Tools, type:
xcode-select --install
- The following tools are required:
autoconf, automake, gsed, bc, bison, curl, dejagnu, expect, flex, gawk, gperf, libtool, patchutils and texinfo.
To check if the tool is installed:
which <tool>
These are my installed tool information:
- autoconf
Automatic configure script builder
which autoconf
/opt/local/bin/autoconf
autoconf --version
autoconf (GNU Autoconf) 2.71
If not found, install this tool: brew install autoconf
- automake
Tool for generating GNU Standards-compliant Makefiles
which automake
/opt/local/bin/automake
automake --version
automake (GNU automake) 1.16.3
If not found, install this tool: brew install automake
- gsed
GNU sed
which gsed
/opt/local/bin/gsed
gsed --version
gsed (GNU sed) 4.8
If not found, install this tool: brew install gnu-sed
- bc
Arbitrary precision numeric processing language
which bc
/usr/bin/bc
bc --version
bc 1.06
If not found, install this tool: brew install bc
- bison
Parser generator
which bison
/usr/bin/bison
bison --version
bison (GNU Bison) 2.3
This tool is installed with the Mac OSX Command Line Tools.
- curl
Get a file from an HTTP, HTTPS or FTP server
which curl
/opt/local/bin/curl
curl --version
curl 7.75.0 (x86_64-apple-darwin18.7.0) libcurl/7.75.0 OpenSSL/1.1.1j zlib/1.2.11 zstd/1.4.9 libidn2/2.3.0 libpsl/0.21.1 (+libidn2/2.3.0)
If not found, install this tool: brew install curl
- dejagnu
Framework for testing other programs
which dejagnu
/usr/local/bin/dejagnu
dejagnu --version
dejagnu auxiliary launcher (DejaGnu) 1.6.3
If not found, install this tool: brew install deja-gnu
- expect
Framework for testing other programs
which expect
/usr/bin/expect
expect -v
expect version 5.45
If not found, install this tool: brew install expect
- flex
Fast Lexical Analyzer, generates Scanners (tokenizers)
which flex
/usr/bin/flex
flex --version
flex 2.6.4 Apple(flex-34)
This tool is installed with the Mac OSX Command Line Tools.
- gawk
GNU awk utility
which gawk
/usr/local/bin/gawk
gawk --version
GNU Awk 5.1.1, API: 3.1 (GNU MPFR 4.1.0, GNU MP 6.2.1)
If not found, install this tool: brew install expect
- gperf
Perfect hash function generator
which gperf
/usr/bin/gperf
gperf --version
GNU gperf 3.0.3
This tool is installed with the Mac OSX Command Line Tools.
- libtool
Generic library support script
which libtool
/usr/local/opt/libtool/libexec/gnubin/libtool
libtool --version
GNU gperf 3.0.3
This tool is installed with the Mac OSX Command Line Tools.
- patchutils
Small collection of programs that operate on patch files.
One of these programs is filterdiff.
To check if patchutils is installed, check if filterdiff is installed.
which filterdiff
/usr/local/bin/filterdiff
filterdiff --version
filterdiff - patchutils version 0.4.2
Better yet, type:
brew info patchutils
patchutils: stable 0.4.2 (bottled), HEAD
Small collection of programs that operate on patch files
http://cyberelk.net/tim/software/patchutils/
/usr/local/Cellar/patchutils/0.4.2 (41 files, 340.1KB)
If not found, install this tool: brew install patchutils
- texinfo
Official documentation format of the GNU project
brew info texinfo
texinfo: stable 6.8 (bottled) [keg-only]
Official documentation format of the GNU project
https://www.gnu.org/software/texinfo/
/usr/local/Cellar/texinfo/6.8 (409 files, 7.6MB)
texinfo is keg-only, which means it was not symlinked into /usr/local,
because macOS already provides this software and installing another
version in parallel can cause all kinds of trouble.
If you need to have texinfo first in your PATH, run:
echo 'export PATH="/usr/local/opt/texinfo/bin:$PATH"' >> /Users/robertlie/.bash_profile
If not found, install this tool: brew install texinfo
Update PATH in .bash_profile
Type: cd ~
Type: nano .bash_profile
Type: export PATH=/usr/local/opt/texinfo/bin:$PATH
- Create a riscv_toolchain directory:
Type: cd ~
Type: mkdir riscv_toolchain
- The Nuclei RISC-V GNU Compiler Toolchain git repository uses submodules.
You need the --recursive option to fetch the submodules automatically.
The Nuclei maintained source code is located in nuclei-multilib branch, please use this branch.
Type: cd riscv_toolchain
Type: mkdir install
Type: git clone https://github.com/riscv-mcu/riscv-gnu-toolchain
Type: cd riscv-gnu-toolchain
Type: git checkout nuclei-multilib
Type: git submodule update --init --recursive
To show the last commit on this branch, type: git log
~/riscv_toolchain/riscv-gnu-toolchain$ git log
commit ec7d6ba3f72b7c83964a8910b4e2b4756a66eac4 (HEAD -> nuclei-multilib, origin/nuclei-multilib, origin/HEAD)
After executing "git submodule update ..", the file ~/riscv_toolchain/riscv-gnu-toolchain/riscv-gcc/gcc/BASE-VER contains version number 9.2.0.
You will see this version number appear in generated folders and filenames during the build.
I am mentioning this, just in case you wonder were this number comes from.
- Create directory ~/riscv_toolchain/riscv-gnu-toolchain/build where the build is stored.
Type: mkdir build
- Set CFLAGS to avoid build errors in macOS.
Type: export CFLAGS="-Wno-error=implicit-function-declaration"
In Xcode 12 whenever a function is used before being declared it generates an error.
This flag is basically telling the compiler to ignore the error whenever a function is used before being declared.
By settings the above mentioned CFLAGS, the following errors will be avoided:
/Users/robertlie/riscv_toolchain/riscv-gnu-toolchain/riscv-gdb/readline/rltty.c:83:7: error: implicit declaration of function 'ioctl' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
if (ioctl (tty, TIOCGWINSZ, &w) == 0)
/Users/robertlie/riscv_toolchain/riscv-gnu-toolchain/riscv-gdb/readline/rltty.c:720:3: error: implicit declaration of function 'ioctl' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
ioctl (fildes, TIOCSTART, 0);
/Users/robertlie/riscv_toolchain/riscv-gnu-toolchain/riscv-gdb/readline/rltty.c:759:3: error: implicit declaration of function 'ioctl' is invalid in C99 [-Werror,-Wimplicit-function-declaration]
ioctl (fildes, TIOCSTOP, 0);
3 errors generated.
make[3]: *** [rltty.o] Error 1
... and ...
checking target system type... (cached) riscv-nuclei-elf
configure: creating ./config.status
config.status: creating Makefile
make[1]: *** [all] Error 2
make: *** [stamps/build-gdb-newlib] Error 2
- To build the Nuclei RISC-V GNU Compiler Toolchain the GNU Autotools are used.
The GNU Autotools, also known as the GNU Build System, is a suite of programming tools designed to assist in making source code packages portable to many Unix-like systems.
The two most important tools are autoconf and automake.
-
Autoconf is a tool for producing configure scripts for building, installing, and packaging software on computer systems where a Bourne shell is available.
In short the autoconf tool uses the configure.ac as input and generates a Makefile.
Note:
The ~/riscv_toolchain/riscv-gnu-toolchain/configure tool is a shell script.
More information about the many configure options, type: ./configure --help
See also: configure_help.txt
To show the version, type:
./configure --version
riscv-toolchain configure 1.0 generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it.
-
Automake is a programming tool to automate parts of the compilation process.
It eases usual compilation problems. For example, it points to needed dependencies.
In short the automake tool uses the Makefile as input executes the compilation process.
Make sure the make tool is installed, type:
which make
/usr/bin/make
To show the version, type:
make --version
GNU Make 3.81
Copyright (C) 2006 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.
There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
This program built for i386-apple-darwin11.3.0
The make tool should be available after installing the Mac OSX Command Line Tools.
- Create the Makefile.
Type: cd build
Type: ../configure --prefix=`pwd`/../../install \
--enable-multilib --with-cmodel=medany
You will see the following:
After a few seconds a ~/riscv_toolchain/riscv-gnu-toolchain/build/Makefile is generated.
- Build the toolchain.
Type: make
- More infornation about the configure options:
- --with-arch
Sets the base RISC-V ISA, if not set defaults to rv64imafdc.
Controls which instructions set and registers to use.
The RISC-V toolchain support three base ISAs (v2.2):
- rv32i: A load-store ISA with 32, 32-bit general purpose int registers.
- rv32e: rv32i with only 16 int registers, for embedded.
- rv64i: 64-bit flavor of rv32i general purpose int registers are 64-bits.
Plus these extensions:
- m: Integer multiplication and division.
- a: Atomic instructions.
- f: Single-Precision floating-point.
- d: Double-Precision floating-point.
- c: Compressed instructions.
- g: General, a shortcut to imafd.
Append extensions to base ISA, for example: --with-arch=rv32im, --with-arch=rv64imafdc
- --with-abi
Sets the base RISC-V ABI (Application Binary Interface), if not set defaults to lp64d.
Controls the calling convention (which arguments are passed into which registers) and the layout of data in memory.
Two integer ABIs and three floating-point ABIs, which together are treated as a single ABI string.
Two integer ABIs follow the standard ABI naming scheme:
- ilp32:
int, long, and pointers are all 32-bits long.
long long is a 64-bit type.
char is 8-bit.
short is 16-bit.
- lp64:
long and pointers are 64-bits long.
int is a 32-bit type.
The other types remain the same as ilp32.
Three floating-point ABIs are RISC-V specific addition:
- "" (the empty string): No floating-point arguments are passed in registers.
- f: 32-bit and smaller floating-point arguments are passed in registers.
This ABI requires the f extension, as without f there are no floating point registers.
- d: 64-bit and smaller floating-point arguments are passed in registers.
This ABI requires the d extension.
Examples:
- --with-arch=rv32imafdc --with-abi=ilp32d:
Hardware floating-point instructions can be generated and floating-point arguments are passed in registers.
- --with-arch=rv32imac --with-abi=ilp32:
No floating-point instructions can be generated and no floating-point arguments are passed in registers.
- --with-arch=rv32imafdc --with-abi=ilp32:
Hardware floating-point instructions can be generated, but no floating-point arguments will be passed in registers.
- --with-arch=rv32imac --with-abi=ilp32d:
Illegal, as the ABI requires floating-point arguments are passed in registers but the ISA defines no floating-point registers to pass them in.
- --with-cmodel
RISC-V has two code models, namely medlow (medium-low) and medany (medium-any).
Select the code model to use when building libc and libgcc.
- --with-cmodel=medlow
Generate code for the medium-low code model.
The program and its statically defined symbols must lie within a single 2 GiB address range and must lie between absolute addresses -2 GiB and +2 GiB. lui and addi pairs are used to generate addresses. Programs can be statically or dynamically linked.
- --with-cmodel=medany
Generate code for the medium-any code model.
The program and its statically defined symbols must lie within a single 4GiB address range. auipc and addi pairs are used to generate addresses. Programs can be statically or dynamically linked.
- --enable-multilib
Build both RV32 and RV64 runtime libraries.
If not set, the default --disable-multilib is used.
If --enable-multilib is used and AFTER the toolchain is build, check the created runtime libraries:
Type: cd ~/riscv_toolchain/install/bin
Type: ./riscv-nuclei-elf-gcc --print-multi-lib
This will display the mapping between command line options (for example: @march=rv32i@mabi=ilp32) and multiple library search directories (for example: rv32i/ilp32).
rv32i/ilp32;@march=rv32i@mabi=ilp32
rv32ic/ilp32;@march=rv32ic@mabi=ilp32
rv32im/ilp32;@march=rv32im@mabi=ilp32
rv32imc/ilp32;@march=rv32imc@mabi=ilp32
rv32iac/ilp32;@march=rv32iac@mabi=ilp32
rv32imac/ilp32;@march=rv32imac@mabi=ilp32
rv32imafc/ilp32f;@march=rv32imafc@mabi=ilp32f
rv32imafdc/ilp32d;@march=rv32imafdc@mabi=ilp32d
rv32e/ilp32e;@march=rv32e@mabi=ilp32e
rv32ec/ilp32e;@march=rv32ec@mabi=ilp32e
rv32emc/ilp32e;@march=rv32emc@mabi=ilp32e
rv32emac/ilp32e;@march=rv32emac@mabi=ilp32e
rv32eac/ilp32e;@march=rv32eac@mabi=ilp32e
rv64i/lp64;@march=rv64i@mabi=lp64
rv64im/lp64;@march=rv64im@mabi=lp64
rv64imc/lp64;@march=rv64imc@mabi=lp64
rv64imac/lp64;@march=rv64imac@mabi=lp64
rv64imafc/lp64f;@march=rv64imafc@mabi=lp64f
rv64imafdc/lp64d;@march=rv64imafdc@mabi=lp64d
The above mentioned libraries, for example rv32i/ilp32, can be found at:
~/riscv_toolchain/install/lib/gcc/riscv-nuclei-elf/9.2.0
- Here are some other useful informtion:
- The Sipeed Logan Nano CPU is a GigaDevice GD32VF103CBT6, based on Nuclei System Technology Bumblebee core.
The Nuclei Bumblebee core supports the RISC-V ISA version 2.2 RV32IMAC instruction set.
This means the GD32VF103CBT6 has no floating-point support.
- When option --enable-multilib is used and when using the Sipeed Logan Nano development board the riscv-nuclei-elf-gcc tool should be used as follow:
Type: ./riscv-nuclei-elf-gcc inputfile.c -march=rv32imac \
-mabi=ilp32 -o outputfile
The -march=rv32imac and -mabi=ilp32 settings can be found in:
Nuclei SDK Release 0.3.5-dev pdf file, Sipeed Logan Nano CORE=n205,
see Table 6: Supported Nuclei Processor cores.
By setting -march and -mabi the riscv-nuclei-elf-gcc tool can find the appropriate libraries, for example:
~/riscv_toolchain/install/lib/gcc/riscv-nuclei-elf/9.2.0/rv32imac/ilp32
- If you do not use --enable-multilib and only set --with-arch and --with-abi, for example:
Type: ./configure --prefix=`pwd`/../../install --with-arch=rv32imac \
--with-abi=ilp32 --with-cmodel=medlow
... than a library is created for only rv32imac - ilp32.
The build is faster, approximately 30 minutes.
If you type:
./riscv-nuclei-elf-gcc --print-multi-lib
you will see:
.;
In this case, there is no need to set --with-arch and --with-abi when using the riscv-nuclei-elf-gcc tool:
Type: ./riscv-nuclei-elf-gcc inputfile.c -o outputfile
You can still set --with-arch and --with-abi but the search directory (".") will be:
~/riscv_toolchain/install/lib/gcc/riscv-nuclei-elf/9.2.0/.
- Both configure settings:
./configure --prefix=`pwd`/../../install --enable-multilib \ --with-arch=rv32imac --with-abi=ilp32 --with-cmodel=medlow
./configure --prefix=`pwd`/../../install --enable-multilib \ --with-cmodel=medlow
... will generate the same result.
In both cases the same multiple libraries will be created.
Both builds takes, approximately 1 hour and 15 minutes.
The --with-arch and --with-abi options are ignored when using --enable-multilib
- Download extra prerequisites: (gmp, mpfr, mpc and isl).
- gmp
GNU multiple precision arithmetic library
- mpfr
C library for multiple-precision floating-point computations
- libmpc
C library for the arithmetic of high precision complex numbers
- isl
Integer Set Library for the polyhedral model
More info, see: ~/riscv_toolchain/riscv-gnu-toolchain/riscv-gcc/contrib/download_prerequisites
Type: cd ~/riscv_toolchain/riscv-gnu-toolchain
Type: cd ./riscv-gcc/ && ./contrib/download_prerequisites
The four compressed files (gmp, mpfr, mpc and isl) are downloaded and unpacked in:
~/riscv_toolchain/riscv-gnu-toolchain/riscv-gcc
- Return to ~/riscv_toolchain/riscv-gnu-toolchain/build
Type: cd build
- Replace the word "unknown" to "nuclei" in the generated Makefile.
Type (one line):
sed -i -e 's/make_tuple = riscv$(1)-unknown-$(2)/make_tuple = riscv-nuclei-$(2)/g' Makefile
This will change the tool names from riscv-unknown-elf-xxx to riscv-nuclei-elf-xxx.
- Build ELF/Newlib toolchain, it will take approx. 1 hour and 15 min depending on your machine
Type: make -j`nproc`
The RISC-V C and C++ cross-compiler supports two build modes:
- If you type: make linux -j`nproc`
You will build the Linux-ELF/glibc toolchain.
The GNU C Library, commonly known as glibc, is the GNU Project's implementation of the C standard library.
Glibc is focused in full functionality.
Glibc can be used to build programs that can be dynamically linked and executed on an OS like Linux.
- If you type: make -j`nproc`
You will build a generic ELF/Newlib toolchain.
Newlib is a complete C library implementation and is used for small statically linked standalone programs and embedded targets.
Newlib is smaller than regular glibc.
- If you compile with -nostartfiles -nostdlib -nostdinc both the toolchains will work the same way.
More make options
- Update PATH in .bash_profile
Type: cd ~
Type: nano .bash_profile
Type: export PATH=$PATH:/Users/robertlie/riscv_toolchain/install/bin
- Check the ~/riscv_toolchain/install/bin folder for the generated
riscv-gnu-toolchain tools. These tools are prefixed by riscv-nuclei-elf-.
-
riscv-nuclei-elf-addr2line
Convert addresses into file names and line numbers.
-
riscv-nuclei-elf-ar
The GNU ar program creates, modifies, and extracts from archives.
-
riscv-nuclei-elf-as
The GNU Assembler, commonly known as gas or as, is the assembler developed by the GNU Project.
-
riscv-nuclei-elf-c++
The GNU C and C++ compiler.
The tools riscv-nuclei-elf-c++, riscv-nuclei-elf-cpp, riscv-nuclei-elf-g++, riscv-nuclei-elf-gcc and riscv-nuclei-elf-gcc-9.2.0 are the same.
-
riscv-nuclei-elf-c++filt
c++filt - Demangle C++ and Java symbols.
-
riscv-nuclei-elf-cpp
The GNU C and C++ compiler.
The tools riscv-nuclei-elf-c++, riscv-nuclei-elf-cpp, riscv-nuclei-elf-g++, riscv-nuclei-elf-gcc and riscv-nuclei-elf-gcc-9.2.0 are the same.
-
riscv-nuclei-elf-elfedit
Update ELF header and program property of ELF files
-
riscv-nuclei-elf-g++
The GNU C and C++ compiler.
The tools riscv-nuclei-elf-c++, riscv-nuclei-elf-cpp, riscv-nuclei-elf-g++, riscv-nuclei-elf-gcc and riscv-nuclei-elf-gcc-9.2.0 are the same.
-
riscv-nuclei-elf-gcc
The GNU C and C++ compiler.
The tools riscv-nuclei-elf-c++, riscv-nuclei-elf-cpp, riscv-nuclei-elf-g++, riscv-nuclei-elf-gcc and riscv-nuclei-elf-gcc-9.2.0 are the same.
-
riscv-nuclei-elf-gcc-9.2.0
The GNU C and C++ compiler.
The tools riscv-nuclei-elf-c++, riscv-nuclei-elf-cpp, riscv-nuclei-elf-g++, riscv-nuclei-elf-gcc and riscv-nuclei-elf-gcc-9.2.0 are the same.
-
riscv-nuclei-elf-gcc-ar
A wrapper around ar adding the --plugin option
-
riscv-nuclei-elf-gcc-nm
A wrapper around nm adding the --plugin option
-
riscv-nuclei-elf-gcc-ranlib
A wrapper around ranlib adding the --plugin option
-
riscv-nuclei-elf-gcov
gcov is a tool you can use in conjunction with GCC to test code coverage in your programs.
-
riscv-nuclei-elf-gcov-dump
gcov-dump is a tool you can use in conjunction with GCC to dump content of gcda and gcno profile files offline.
-
riscv-nuclei-elf-gcov-tool
gcov-tool is an offline tool to process gcc's gcda profile files.
-
riscv-nuclei-elf-gdb
The GNU Debugger (GDB).
-
riscv-nuclei-elf-gdb-add-index
Add index files to speed up GDB.
-
riscv-nuclei-elf-gprof
GNU profiler, to determine which parts of a program are taking most of the execution time.
-
riscv-nuclei-elf-ld
The GNU linker.
GNU ld runs the linker, which creates an executable file (or a library) from object files created during compilation of a software project.
-
riscv-nuclei-elf-ld.bfd
The linker accesses object and archive files using the BFD libraries.
-
riscv-nuclei-elf-nm
List symbols from object files.
-
riscv-nuclei-elf-objcopy
The GNU objcopy utility copies the contents of an object file to another.
Examples:
Creating hex file from elf file:
Type: riscv-nuclei-elf-objcopy -O ihex firmware.elf firmware.hex
Creating bin file from elf file:
Type: riscv-nuclei-elf-objcopy -S -O binary firmware.elf firmware.bin
Note:
-S removes all symbol and relocation information.
-
riscv-nuclei-elf-objdump
objdump displays information about one or more object files. T
Examples:
riscv-nuclei-elf-objdump firmware.elf -xS > firmware.S
-
riscv-nuclei-elf-ranlib
ranlib generates an index to the contents of an archive and stores it in the archive.
-
riscv-nuclei-elf-readelf
readelf displays information about one or more ELF format object files.
-
riscv-nuclei-elf-run
GNU simulator (SIM).
A gdb simulator RISC-V port, and works the same as other gdb simulators.
-
riscv-nuclei-elf-size
GNU size.
The GNU size utility lists the section sizes and the total size for each of the binary files objfile on its argument list.
-
riscv-nuclei-elf-strings
GNU strings.
strings is a program that finds and prints text strings embedded in binary files such as executables.
-
riscv-nuclei-elf-strip
GNU strip.
GNU strip discards all symbols fand other data from object files.
For version information:
Type: riscv-nuclei-elf-gcc --version
For help information:
Type: riscv-nuclei-elf-gcc --help
You can use the riscv-nuclei-elf-gcc tool to show how the configure script was configured:
Type: riscv-nuclei-elf-gcc -v
The following message is shown:
Using built-in specs.
COLLECT_GCC=./riscv-nuclei-elf-gcc
COLLECT_LTO_WRAPPER=/Users/robertlie/riscv_toolchain/install/bin/
../libexec/gcc/riscv-nuclei-elf/9.2.0/lto-wrapper
Target: riscv-nuclei-elf
Configured with: /Users/robertlie/riscv_toolchain/riscv-gnu-toolchain/
build/../riscv-gcc/configure
--target=riscv-nuclei-elf
--prefix=/Users/robertlie/riscv_toolchain/riscv-gnu-toolchain/build/
../../install
--disable-shared
--disable-threads
--enable-languages=c,c++
--with-system-zlib
--enable-tls
--with-newlib
--with-sysroot=/Users/robertlie/riscv_toolchain/riscv-gnu-toolchain/build/
../../install/riscv-nuclei-elf
--with-native-system-header-dir=/include
--disable-libmudflap
--disable-libssp
--disable-libquadmath
--disable-libgomp
--disable-nls
--src=.././riscv-gcc
--enable-checking=yes
--enable-multilib
--with-abi=lp64d
--with-arch=rv64imafdc
--with-tune=rocket
'CFLAGS_FOR_TARGET=-Os -mcmodel=medany'
'CXXFLAGS_FOR_TARGET=-Os -mcmodel=medany'
Thread model: single
gcc version 9.2.0 (GCC)
Note:
If you do not specify --with-arch and --with-abi the default will be
--with-arch=rv64imafdc and --with-abi=lp64d
- After the build, two libraries were created:
- GCC low-level runtime library (libgcc.a)
Handle arithmetic operations that the target processor cannot perform directly (e.g., floating point emulation)
Location: ~/riscv_toolchain/install/lib/gcc/riscv-nuclei-elf/9.2.0/rv32imac/ilp32
-
crtbegin.o
GCC uses this to find the start of the constructors.
-
crtend.o
GCC uses this to find the start of the destructors.
-
crti.o
Defines the function prologs for the .init and .fini sections.
-
crtn.o
Defines the function epilogs for the .init/.fini sections.
-
libgcov.a
Library used by gcov test coverage program (using "--coverage").
gcov is a test coverage program. Use it in concert with GCC to analyze your
programs to help create more efficient, faster running code and to discover untested parts of your program.
- Newlib is a C standard library implementation intended for use on embedded systems.
Includes several components (libc.a, libm.a, ...)
Location: ~/riscv_toolchain/install/riscv-nuclei-elf/lib/rv32imac/ilp32
- Test the generated tools.
- Open a terminal.
Type: cd ~/riscv_toolchain
- Write a test program.
Create a file ~/riscv_toolchain/hello.c with the following content:
#include <stdio.h>
int main(void) {
printf("Hello World\n");
return 0;
}
- Compile the test program (for arch=rv32imac and abi=ilp32) into the compatible RISC-V instruction code that can be executed on the processor.
Type: riscv-nuclei-elf-gcc hello.c -O2 -march=rv32imac -mabi=ilp32 \
-o hello
If you did not specify -march=rv32imac and -mabi=ilp32 the default -march=rv64imafdc and -mabi=lp64d is used.
See: riscv-nuclei-elf-gcc -v
Type: file hello
Output:
hello: ELF 32-bit LSB executable, UCB RISC-V, RVC, soft-float ABI, version 1 (SYSV), statically linked, not stripped
Type: ./hello
Output:
-bash: ./hello: cannot execute binary file
The hello program has been compiled for the riscv32 platform, and thus, will not run on macOS unless it is compatible.
You can use spike, which is a RISC-V ISA simulator which run programs in a user space as if it is on a RISC-V hardware.
See: How to build Spike emulator and Proxy Kernel (PK) on macOS
- Inspect the output binary.
Type: riscv-nuclei-elf-readelf -a hello | less
Output:
riscv_readelf.txt
Type: riscv-nuclei-elf-objdump -d hello | less
Output:
riscv_objdump.txt
- Assemble and link with gcc/binutils.
Type: riscv-nuclei-elf-gcc hello.c -S -march=rv32imac -mabi=ilp32 -o hello.S
Output:
hello.S.txt
Type: riscv-nuclei-elf-gcc hello.S -c -march=rv32imac -mabi=ilp32 -o hello
- A note to myself:
PlatformIO supports the Sipeed Longan Nano development board for Windows and Linux OS.
I was curious how the Nuclei developers configured the RISCV toolchain configure script for Windows.
I downloaded and unpacked toolchain-gd32v-windows_x86-9.2.0.tar.gz on Windows 10 computer.
Type: cd toolchain-gd32v-windows_x86-9.2.0\bin
Type: riscv-nuclei-elf-gcc.exe -v
The following message is shown:
Using built-in specs.
COLLECT_GCC=.\riscv-nuclei-elf-gcc.exe
COLLECT_LTO_WRAPPER=c:/users/robertlie/.platformio/packages/
toolchain-gd32v/bin/../libexec/gcc/riscv-nuclei-elf/9.2.0/lto-wrapper.exe
Target: riscv-nuclei-elf
Configured with: /home/share/toolchain/riscv-gnu-toolchain/riscv-gcc/configure
--target=riscv-nuclei-elf
--host=i686-w64-mingw32
--prefix=/home/share/toolchain/build/rv_win_bare_1908291308
--disable-shared
--disable-threads
--enable-languages=c,c++
--with-system-zlib
--enable-tls
--with-newlib
--with-sysroot=/home/share/toolchain/build/rv_win_bare_1908291308/
riscv-nuclei-elf
--with-native-system-header-dir=/include
--disable-libmudflap
--disable-libssp
--disable-libquadmath
--disable libgomp
--disable-nls
--src=.././riscv-gcc
--enable-checking=yes
--enable-multilib
--with-abi=ilp32d
--with-arch=rv32gc
--with-tune=rocket
'CFLAGS_FOR_TARGET=-Os -mcmodel=medlow'
'CXXFLAGS_FOR_TARGET=-Os -mcmodel=medlow'
Thread model: single
gcc version 9.2.0 (GCC)
|