RISC-V

 
 
RISC-V is an open standard instruction set architecture (ISA) based on established reduced instruction set computer (RISC) principles. The RISC-V ISA is provided under open source licenses that do not require fees to use.

More information about RISC-V can be found at:
https://riscv.org/








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

    Build Nuclei 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:

    Configure riscv-gnu-toolchain

    After a few seconds a ~/riscv_toolchain/riscv-gnu-toolchain/build/Makefile is generated.

    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: @[email protected]=ilp32) and multiple library search directories (for example: rv32i/ilp32).

      rv32i/ilp32;@[email protected]=ilp32
      rv32ic/ilp32;@[email protected]=ilp32
      rv32im/ilp32;@[email protected]=ilp32
      rv32imc/ilp32;@[email protected]=ilp32
      rv32iac/ilp32;@[email protected]=ilp32
      rv32imac/ilp32;@[email protected]=ilp32
      rv32imafc/ilp32f;@[email protected]=ilp32f
      rv32imafdc/ilp32d;@[email protected]=ilp32d
      rv32e/ilp32e;@[email protected]=ilp32e
      rv32ec/ilp32e;@[email protected]=ilp32e
      rv32emc/ilp32e;@[email protected]=ilp32e
      rv32emac/ilp32e;@[email protected]=ilp32e
      rv32eac/ilp32e;@[email protected]=ilp32e
      rv64i/lp64;@[email protected]=lp64
      rv64im/lp64;@[email protected]=lp64
      rv64imc/lp64;@[email protected]=lp64
      rv64imac/lp64;@[email protected]=lp64
      rv64imafc/lp64f;@[email protected]=lp64f
      rv64imafdc/lp64d;@[email protected]=lp64d


      The above mentioned libraries, for example rv32i/ilp32, can be found at:
      ~/riscv_toolchain/install/lib/gcc/riscv-nuclei-elf/9.2.0

      Created muliple libraries

    • 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

    Download prerequisites riscv-gnu-toolchain

    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

      libgcc 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

      newlib 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)