Skip to content

Instantly share code, notes, and snippets.

@44670
Last active August 30, 2023 11:41
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save 44670/30a742f317b52780c41f3d6e256f218c to your computer and use it in GitHub Desktop.
Save 44670/30a742f317b52780c41f3d6e256f218c to your computer and use it in GitHub Desktop.
Building upstream RISC-V GCC+binutils+newlib: the quick and dirty way
Building upstream RISC-V GCC+binutils+newlib: the quick and dirty way
September 5, 2017
There are a number of available options for building a RISC-V GCC toolchain. You might use the build system from the riscv/riscv-tools repository, or investigate toolchain generators such as crosstool-ng. However in the case of riscv-tools, it’s not always clear how this corresponds to the code in the relevant upstream projects. When investigating a potential bug, you often just want to build the latest upstream code with as little fuss as possible. For distribution purposes you’d probably want to perform a proper multi-stage build, but for a quick test you might find the following recipe useful:
git clone --depth=1 git://gcc.gnu.org/git/gcc.git gcc
git clone --depth=1 git://sourceware.org/git/binutils-gdb.git
git clone --depth=1 git://sourceware.org/git/newlib-cygwin.git
mkdir combined
cd combined
ln -s ../newlib-cygwin/* .
ln --force -s ../binutils-gdb/* .
ln --force -s ../gcc/* .
mkdir build
cd build
../configure --target=riscv32-unknown-elf --enable-languages=c \
--disable-shared --disable-threads --disable-multilib --disable-gdb \
--disable-libssp --with-newlib \
--with-arch=rv32ima --with-abi=ilp32 --prefix=$(pwd)/built
make -j$(nproc)
make install
This will produce a newlib toolchain targeting RV32IMA in the built/ subdirectory. When files are duplicated in the newlib, binutils and gcc repositories, the gcc version takes precedence.
Major credit to everyone who worked on getting these toolchain ports upstream (Kito Cheng, Palmer Dabbelt, and others).
@44670
Copy link
Author

44670 commented Oct 25, 2020

How to fix "Error: non-constant .uleb128 is not supported":

Step 1: patch combined/gcc/configure.ac

--- a/gcc/configure.ac
+++ b/gcc/configure.ac
@@ -2961,35 +2961,9 @@ AC_MSG_RESULT($gcc_cv_ld_ro_rw_mix)
 
 gcc_AC_INITFINI_ARRAY
 
-# Check if we have .[us]leb128, and support symbol arithmetic with it.
-gcc_GAS_CHECK_FEATURE([.sleb128 and .uleb128], gcc_cv_as_leb128,
-  [elf,2,11,0],,
-[	.data
-	.uleb128 L2 - L1
-L1:
-	.uleb128 1280
-	.sleb128 -1010
-L2:],
-[[# GAS versions before 2.11 do not support uleb128,
-  # despite appearing to.
-  # ??? There exists an elf-specific test that will crash
-  # the assembler.  Perhaps it's better to figure out whether
-  # arbitrary sections are supported and try the test.
-  as_ver=`$gcc_cv_as --version 2>/dev/null | sed 1q`
-  if echo "$as_ver" | grep GNU > /dev/null; then
-    as_vers=`echo $as_ver | sed -n \
-	-e 's,^.*[	 ]\([0-9][0-9]*\.[0-9][0-9]*.*\)$,\1,p'`
-    as_major=`expr "$as_vers" : '\([0-9]*\)'`
-    as_minor=`expr "$as_vers" : '[0-9]*\.\([0-9]*\)'`
-    if test $as_major -eq 2 && test $as_minor -lt 11
-    then :
-    else gcc_cv_as_leb128=yes
-    fi
-  fi]],
-  [AC_DEFINE(HAVE_AS_LEB128, 1,
-    [Define if your assembler supports .sleb128 and .uleb128.])],
-  [AC_DEFINE(HAVE_AS_LEB128, 0,
-    [Define if your assembler supports .sleb128 and .uleb128.])])
+gcc_cv_as_leb128=no
+AC_DEFINE(HAVE_AS_LEB128, 0,
+    [Define if your assembler supports .sleb128 and .uleb128.])
 
 # Determine if an .eh_frame section is read-only.
 gcc_fn_eh_frame_ro () {

Step 2: Regenerate configure file with autoconf command.

References:
https://gcc.gnu.org/legacy-ml/gcc-patches/2020-02/msg00468.html

@GPSBabelDeveloper
Copy link

If you want a stable tree that's known to work well with RISC-V, the RISC-V organization maintains a tree that's awesome. It doesn't chase the build-of-the-day, but it has tags of everything (assembler, linker, compiler, simulator, openocd, etc.) you need to succeed. I really appreciate that team for doing the integration work because it's hard to figure out if a compiler is emitting a bad opcode or the assembler just isn't new enough to accept a new opcode and so on. Debuggers are even worse.

This is what's used in the MacOS Homebrew RISC-V tools. You can squint through the Ruby and find inspiration in their patches, tags, and build recipies. Homebrew syncs to the riscv-collab tree and sprinkles a tad of magic Mac dust and usability to serve a wide audience of chips and needs.

Risc64-blah is the default; 32-bits are available by twiddling -march and -mabi in your Makefile. As a result of all the languages and multilibs built, the tree will be heavier than yours, but you can use your configure syntax and their git tree and sweeten to taste.

Thanx for helping advance RISC-V.

@44670
Copy link
Author

44670 commented Jan 21, 2022

Thanks for sharing.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment