riscv-collab / riscv-gnu-toolchain

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

How to build a native gcc for riscv (or mean Canadian cross?) #825

Closed lixeon closed 3 years ago

lixeon commented 3 years ago

now, i have x86-ubuntu and riscv-toolchains , so i can build "helloworld" which can be run at riscv. And there are a machine which chip just support ISA rv64imafd (No Compress Instruction), so when i build the toolchain the configure is --with-arch=rv64imafd , like this pic below.

image

so, i wanna build a GCC and then Rustc (better is static binary) and so on which can be run on real riscv-linux. (I mean in a riscv machine to run GCC and Rustc...). i read some issue then also very confused, perhaps this is called Canadian cross? cuz the riscv machine 's resource very small and slow, so i must use x86-ubuntu to do this.

I tryed in gcc source and use configure ../configure CC=riscv64-unknown-linux-gnu-gcc CXX=riscv64-unknown-linux-gnu-c++ --host=riscv64-linux-gnu --enable-languages=c,c++ --disable-multilib --with-abi=lp64d --with-arch=rv64imafd But failed to make. Could anyone give me a step by step tutorial ? thx.

kito-cheng commented 3 years ago

There is some experimental build rule in the riscv-gnu-toolchain, you can try to run make linux-native to build a native gcc for riscv, and you can found a folder called native in the install path, but it not guarantee to work, it's just experimental for fun, so you might still need lots of work to make it work right.

lixeon commented 3 years ago

There is some experimental build rule in the riscv-gnu-toolchain, you can try to run make linux-native to build a native gcc for riscv, and you can found a folder called native in the install path, but it not guarantee to work, it's just experimental for fun, so you might still need lots of work to make it work right.

thanks for your reply. yes , i use the make linux-native and generate some bin, put it to qemu-riscv64-fedora cant run. loss most header files and when i put them by hand, also cant run "printf" and so on. now, i try use qemu-fedora-rv64gc, there are gcc for it, then i want use this to build native gcc which support rv64imafd agian. And, another question, is it cuz gcc is very complex, mixed with kernel, libgcc and so on, so we cant staticly build a single file gcc?

kito-cheng commented 3 years ago

IIRC I tried to build GCC with static link before, it need some extra setup for that, but you can try to use readelf -d or LD_DEBUG=libs to figure out which library is missing or what happen.

jim-wilson commented 3 years ago

Personally, I think that using riscv-gnu-toolchain to build a native toolchain is the worst possible solution.

The best solution is to use a distro that already has a native gcc. They all do. You can boot the distro in qemu, then start rebuilding packages for rv64g instead of rv64gc. When you have built enough of the base system, then you can boot it on hardware and then continue rebuilding packages you need.

If you don't want to do that, then the next best approach, assuming you already have a target root filesystem, is to make sysroots from the target root filesystem, and then use --with-sysroot when configuring to build the compiler. You will need to build two compilers, one which is build==host==x86_64-linux target=riscv64-linux, and then a second one which is build==x86_64-linux and host==target==riscv64-linux. A sysroot is everything the compiler needs, e.g. /usr/include, /usr/lib, /lib, and the various 64-bit variations of those dirs if any. But of course this is only part of the problem, as you will also need to rebuild glibc for rv64, and all of the other libraries used by the compiler, so this may not be very practical, as this might get complicated.

If you don't already have a target root filesystem, then it gets extremely compilcated, building a linux system from scratch, too complicated to explain here. But you might be able to use a build from scratch system like openembedded, and modify the compiler config to get a rv64g compiler instead of a rv64gc compiler, and then build everything from scratch as rv64g. The SiFive freedom-u-sdk is an oipenembedded config that supports building a full native gcc, so that might work.

lixeon commented 3 years ago

Personally, I think that using riscv-gnu-toolchain to build a native toolchain is the worst possible solution.

The best solution is to use a distro that already has a native gcc. They all do. You can boot the distro in qemu, then start rebuilding packages for rv64g instead of rv64gc. When you have built enough of the base system, then you can boot it on hardware and then continue rebuilding packages you need.

If you don't want to do that, then the next best approach, assuming you already have a target root filesystem, is to make sysroots from the target root filesystem, and then use --with-sysroot when configuring to build the compiler. You will need to build two compilers, one which is build==host==x86_64-linux target=riscv64-linux, and then a second one which is build==x86_64-linux and host==target==riscv64-linux. A sysroot is everything the compiler needs, e.g. /usr/include, /usr/lib, /lib, and the various 64-bit variations of those dirs if any. But of course this is only part of the problem, as you will also need to rebuild glibc for rv64, and all of the other libraries used by the compiler, so this may not be very practical, as this might get complicated.

If you don't already have a target root filesystem, then it gets extremely compilcated, building a linux system from scratch, too complicated to explain here. But you might be able to use a build from scratch system like openembedded, and modify the compiler config to get a rv64g compiler instead of a rv64gc compiler, and then build everything from scratch as rv64g. The SiFive freedom-u-sdk is an oipenembedded config that supports building a full native gcc, so that might work.

thx,jim. i follow your suggestion and create script to use the cross-chain to build riscv-target then get the binary for rv64g, however these bin ( such as cc1,collect2 and so on) very big, together almost 500M (gcc-10.2) , then i use strip all files and change to gcc-8.2 ( do not know why gcc-7.x failed), then size about 100M. set library and some dependencies, then this gcc and run in qemu-virt very well, and will be test on real chip board.