riscv-collab / riscv-gnu-toolchain

GNU toolchain for RISC-V, including GCC
Other
3.54k stars 1.16k forks source link

How to build RISC-V native toolchain? #1427

Closed siserte closed 8 months ago

siserte commented 8 months ago

Hi, I need GCC10 in my RISCV machine. For that reason, I've compiled the toolchain with the following commands in my X86_64 machine:

$ sudo zypper install make lbzip2 texinfo autoconf automake python3 libmpc-devel mpfr-devel gmp-devel gawk  bison flex patchutils gcc gcc-c++ zlib-devel expat-devel
$ git clone https://github.com/riscv-collab/riscv-gnu-toolchain
$ cd riscv-gnu-toolchain
$ git submodule update --init --recursive
$ cd gcc
$ git checkout tags/releases/gcc-10.4.0 -b gcc10
$ ./contrib/download_prerequisites
$ cd ..
$ cd glibc
$ git checkout tags/glibc-2.29 -b glibc2.29
$ cd ..
$ ./configure --prefix=/home/bscuser/gcc10-riscv
$ make linux -j8

Once I have my binaries I've copied them in the RISCV machine

$ uname -a
Linux eupilot-vec 5.18.0-rc1 #2 SMP Thu Jul 13 20:12:06 CEST 2023 riscv64 GNU/Linux
$ file /home/user/gcc10-riscv/bin/riscv64-unknown-linux-gnu-gcc
/home/user/gcc10-riscv/bin/riscv64-unknown-linux-gnu-gcc: ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=d5a868fb72f9a7c6f48d7075768ae5c00de10dfc, for GNU/Linux 3.2.0, with debug_info, not stripped

It looks like it has not been cross-compiled since binaries in the RISCV machine are like:

$ file /usr/bin/ls
/usr/bin/ls: ELF 64-bit LSB pie executable, UCB RISC-V, RVC, double-float ABI, version 1 (SYSV), dynamically linked, interpreter /lib/ld-linux-riscv64-lp64d.so.1, BuildID[sha1]=a66b50807aee2f898662d5cb39a5bfd526027745, for GNU/Linux 4.15.0, stripped

And of course, when I run the compiler I get the following error: error: cannot execute binary file: Exec format error

What am I doing wrong?

Thank you.

TommyMurphyTM1234 commented 8 months ago

What am I doing wrong?

You're building a cross compiler with build-host = x86_64, run-host = x86_64 and target-isa = RISC-V whereas you actually need run-host = RISC-V.

I'm not sure how you achieve this. Maybe using the make linux-native option as I already suggested to you here:

Unfortunately I can't find much useful info on this option. Maybe this is of some help but I'm not sure how up to date it is:

Perhaps @kito-cheng or @cmuellner could comment?

siserte commented 8 months ago

Well, now I am compiling the toolchain in a x86.

Just to be sure, where should I compile the toolchain to execute it in the RISCV, in the x86 or in the RISCV?

I tried to compile it directly in the RISCV and it didn't work neither :(

TommyMurphyTM1234 commented 8 months ago

Just to be sure, where should I compile the toolchain to execute it in the RISCV in the x86 or in the RISCV?

Most likely the latter - i.e. build-host = run-host = target-isa = RISC-V but then you're possibly into GCC "bootstrapping" territory (see the section titled "Building a native compiler" here):

... unless you can use an existing pre-built RISC-V native GCC to build your GCC 10 toolchain. What, if any, RISC-V GCC toolchains does your RISC-V Linux distro software sources provide?

I tried to compile it directly in the RISCV and it didn't work neither :(

It might help to explain what happened/went wrong.

TommyMurphyTM1234 commented 8 months ago

This might also contain some useful info but you should search the open and closed issues and other possible sources of info yourself.

SavageShrimp commented 8 months ago

Hi, I managed to get a native compiler up and running for riscv64 by using the following procedure;

mkdir src cd src sudo apt-get install autoconf automake autotools-dev curl python3 python3-pip libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev ninja-build git cmake libglib2.0-dev git clone https://github.com/riscv/riscv-gnu-toolchain cd riscv-gnu-toolchain/ ./configure --with-cmodel=medany --with-tune=thead-c906 --prefix=/opt/riscv64-cross --with-abi=lp64d --with-arch=rv64imafd make -j6 musl sync cd .. wget https://gmplib.org/download/gmp/gmp-6.3.0.tar.xz wget https://www.mpfr.org/mpfr-current/mpfr-4.2.1.tar.xz wget https://ftp.gnu.org/gnu/mpc/mpc-1.3.1.tar.gz tar xf gmp-6.3.0.tar.xz tar xf mpfr-4.2.1.tar.xz tar xf mpc-1.3.1.tar.gz cd riscv-gnu-toolchain/gcc ln -s ../../gmp-6.3.0 gmp ln -s ../../mpfr-4.2.1 mpfr ln -s ../../mpc-1.3.1 mpc cd .. export PATH=$PATH:/opt/riscv64-cross/bin riscv64-unknown-linux-musl-gcc make clean ./configure --with-cmodel=medany --with-tune=thead-c906 --prefix=/opt/riscv64-native --with-abi=lp64d --with-host=riscv64-unknown-linux-musl --without-system-zlib sed -i 's/^PATH/#PATH/' Makefile sed -i 's/^SYSROOT := $(INSTALL_DIR)\/sysroot/SYSROOT := $(INSTALL_DIR)\//' Makefile sudo mkdir /opt/riscv64-native sudo chown build:build /opt/riscv64-native make -j6 musl tar cv -C/opt -f riscv64-native.tar ./riscv64-native/ cd build-gcc-musl-stage1 make install-strip cd ../build-gcc-musl-stage2 make install-strip cd ../build-binutils-musl/ make install-strip cd .. tar cv -C/opt -f riscv64-native-stripped.tar ./riscv64-native/

As you can see the sysroot needs to be changed (I didn't bother to build without a sysroot) and the native cpu compiler path needs to be removed or it causes build errors.

When building for riscv64 I encountered some errors in binutils, but the following patch fixed them (not sure if this is valid, changes only get it to compile).

binutils-patch.txt

cmuellner commented 8 months ago

I don't see the problem that is being solved here. Also, I don't see why one would prefer GCC 10 over anything more recent.

Regardless of which distro is running on the RISC-V machine, it comes with a host compiler. So if you want another GCC version on that machine, then build that GCC (See section Building a native compiler on the GCC installation instruction page). Ensure the GCC version you are building is compatible with the distro that runs on your RISC-V machine. Using a more recent GCC version often simply works.

This repository is not meant to provide you with a toolchain that serves as a drop-in replacement for the GCC that ships with your Linux distro. If you do that, be prepared to find solutions for missing features in your Linux distro (e.g. missing instructions in Binutils), API issues (e.g. removed functions in glibc), and ABI issues (e.g. new default ABIs, which make components built with the new toolchain incompatible with the components in your Linux distro).

TommyMurphyTM1234 commented 8 months ago

Does this issue need to remain open or can it be closed?

@cmuellner, does what you say imply that the make linux-native build option, which is referred to as experiential and not to be depended on in various issues, is perhaps redundant? If not then in what circumstances might it be used and are there any clear guidance notes on it (I couldn't find anything comprehensive/authoritative)?

SavageShrimp commented 8 months ago

I don't see the problem that is being solved here. Also, I don't see why one would prefer GCC 10 over anything more recent.

Regardless of which distro is running on the RISC-V machine, it comes with a host compiler. So if you want another GCC version on that machine, then build that GCC (See section Building a native compiler on the GCC installation instruction page). Ensure the GCC version you are building is compatible with the distro that runs on your RISC-V machine. Using a more recent GCC version often simply works.

This repository is not meant to provide you with a toolchain that serves as a drop-in replacement for the GCC that ships with your Linux distro. If you do that, be prepared to find solutions for missing features in your Linux distro (e.g. missing instructions in Binutils), API issues (e.g. removed functions in glibc), and ABI issues (e.g. new default ABIs, which make components built with the new toolchain incompatible with the components in your Linux distro).

My apologies, I was trying to build a native compiler for the milk-v duo256 which has no default distribution. This repo proved to be the easiest to adapt in getting a build working and so I decided to post my results here.

cmuellner commented 8 months ago

My apologies, I was trying to build a native compiler for the milk-v duo256 which has no default distribution. This repo proved to be the easiest to adapt in getting a build working and so I decided to post my results here.

No need to apologize.

If a board comes with no Linux distro at all, then you will have to port one.

I just looked up the product page of the MILK-V Duo (https://milkv.io/docs/duo/overview). There I can find that "Buildroot" is supported.

Buildroot works a bit differently than typical binary distributions. If you want to customize it, you have to build an image on your own. So all you have to do is to build your own Buildroot image after changing the build configuration to enable the GCC package. If you have any questions about that, then reach out to Milk-V (they list Buildroot as supported OS, so they should be able to guide you).

cmuellner commented 8 months ago

@cmuellner, does what you say imply that the make linux-native build option, which is referred to as experiential and not to be depended on in various issues, is perhaps redundant? If not then in what circumstances might it be used and are there any clear guidance notes on it (I couldn't find anything comprehensive/authoritative)?

A statically linked native toolchain that has been built with a cross-compiler can be used to build statically linked binaries if all its dependencies are built with the same compiler. That's a rare expert use-case that only works if there is no break in the Linux ABI.

We don't have linux-native documented to avoid people using it with the wrong expectations.

I think this quote from Jim (from the issue that you have referenced) perfectly summarizes everything:

I try to strongly discourage people from using riscv-gnu-toolchain to build linux native compilers because it is very unlikiely to do anything useful. You need a glibc of the same version with same patches and same configure options, which riscv-gnu-toolchain can't give you.

TommyMurphyTM1234 commented 8 months ago

Thanks @cmuellner - so does this issue need to remain open or can it be closed?

cmuellner commented 8 months ago

Thanks @cmuellner - so does this issue need to remain open or can it be closed?

Yes. Building a native RISC-V toolchain is not a supported feature.