riscv-collab / riscv-gnu-toolchain

GNU toolchain for RISC-V, including GCC
Other
3.4k stars 1.13k forks source link

How to build Linux toolchain with custom set of multilibs? #1445

Open rajsureshgeorge opened 5 months ago

rajsureshgeorge commented 5 months ago

I configured the toolchain with ./configure --prefix=/home/user/Riscv_most_combinations --with-multilib-generator="rv32i-ilp32--;rv32ic-ilp32--;rv32iac-ilp32--;rv32im-ilp32--;rv32imc-ilp32--;rv32imac-ilp32--;rv32imafc-ilp32f--;rv32imafdc-ilp32f--;rv32ima-ilp32--;rv32imaf-ilp32--;rv32imafd-ilp32d--;rv32imafdc-ilp32--;rv32imafd-ilp32d--;rv32imafdc-ilp32d--;rv64ima-lp64--;rv64imac-lp64--;rv64imaf-lp64--;rv64imafc-lp64--;rv64imafd-lp64--;rv64imafdc-lp64--;rv64imafd-lp64d--;rv64imafdc-lp64d--;" --with-cmodel=medany

I was able compile newlib successfully with this configuration. I double checked it.

./riscv64-unknown-elf-gcc --print-multi-lib
.;
rv32i/ilp32;@march=rv32i@mabi=ilp32
rv32ic/ilp32;@march=rv32ic@mabi=ilp32
rv32iac/ilp32;@march=rv32iac@mabi=ilp32
rv32im/ilp32;@march=rv32im@mabi=ilp32
rv32imc/ilp32;@march=rv32imc@mabi=ilp32
rv32imac/ilp32;@march=rv32imac@mabi=ilp32
rv32imafc/ilp32;@march=rv32imafc@mabi=ilp32
rv32imafc/ilp32f;@march=rv32imafc@mabi=ilp32f
rv32imafdc/ilp32;@march=rv32imafdc@mabi=ilp32
rv32imafdc/ilp32f;@march=rv32imafdc@mabi=ilp32f
rv32imafdc/ilp32d;@march=rv32imafdc@mabi=ilp32d
rv32ima/ilp32;@march=rv32ima@mabi=ilp32
rv32imaf/ilp32;@march=rv32imaf@mabi=ilp32
rv32imafd/ilp32;@march=rv32imafd@mabi=ilp32
rv32imafd/ilp32d;@march=rv32imafd@mabi=ilp32d
rv64ima/lp64;@march=rv64ima@mabi=lp64
rv64imac/lp64;@march=rv64imac@mabi=lp64
rv64imaf/lp64;@march=rv64imaf@mabi=lp64
rv64imafc/lp64;@march=rv64imafc@mabi=lp64
rv64imafd/lp64;@march=rv64imafd@mabi=lp64
rv64imafd/lp64d;@march=rv64imafd@mabi=lp64d
rv64imafdc/lp64;@march=rv64imafdc@mabi=lp64

But when I am building linux gcc with make linux it is not able to compile properly showing this error:

 echo 'int __libgcc_eh_dummy;' > eh_dummy.c;        \
  /home/user/ToolChain/riscv-gnu-toolchain/build-gcc-linux-stage1/./gcc/xgcc -B/home/user/ToolChain/riscv-gnu-toolchain/build-gcc-linux-stage1/./gcc/ -B/home/user/ToolChain/Riscv_most_combinations/riscv64-unknown-linux-gnu/bin/ -B/home/user/ToolChain/Riscv_most_combinations/riscv64-unknown-linux-gnu/lib/ -isystem /home/user/ToolChain/Riscv_most_combinations/riscv64-unknown-linux-gnu/include -isystem /home/user/ToolChain/Riscv_most_combinations/riscv64-unknown-linux-gnu/sys-include    -O2 -mcmodel=medany -march=rv32imac -mabi=ilp32 -O2  -O2   -mcmodel=medany -DIN_GCC  -DCROSS_DIRECTORY_STRUCTURE  -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition  -isystem ./include  -fPIC -g -DIN_LIBGCC2 -fbuilding-libgcc -fno-stack-protector -Dinhibit_libc -fPIC -I. -I. -I../../../.././gcc -I/home/user/oolChain/riscv-gnu-toolchain/gcc/libgcc -I/home/user/ToolChain/riscv-gnu-toolchain/gcc/libgcc/. -I/home/user/ToolChain/riscv-gnu-toolchain/gcc/libgcc/../gcc -I/home/user/ToolChain/riscv-gnu-toolchain/gcc/libgcc/../include  -DHAVE_CC_TLS   -fvisibility=hidden -DHIDE_EXPORTS -c eh_dummy.c      \
     -o eh_dummy.o;             \
  objects=eh_dummy.o;               \
fi;                         \
/home/user/ToolChain/Riscv_most_combinations/riscv64-unknown-linux-gnu/bin/ar  rc libgcc.a $objects
/home/user/ToolChain/Riscv_most_combinations/riscv64-unknown-linux-gnu/bin/ranlib libgcc.a
/home/user/ToolChain/riscv-gnu-toolchain/build-gcc-linux-stage1/./gcc/xgcc -B/home/user/ToolChain/riscv-gnu-toolchain/build-gcc-linux-stage1/./gcc/ -B/home/user/ToolChain/Riscv_most_combinations/riscv64-unknown-linux-gnu/bin/ -B/home/user/ToolChain/Riscv_most_combinations/riscv64-unknown-linux-gnu/lib/ -isystem /home/user/ToolChain/Riscv_most_combinations/riscv64-unknown-linux-gnu/include -isystem /home/user/ToolChain/Riscv_most_combinations/riscv64-unknown-linux-gnu/sys-include    -O2 -mcmodel=medany -march=rv32imac -mabi=ilp32 -O2  -O2   -mcmodel=medany -DIN_GCC  -DCROSS_DIRECTORY_STRUCTURE  -W -Wall -Wno-narrowing -Wwrite-strings -Wcast-qual -Wstrict-prototypes -Wmissing-prototypes -Wold-style-definition  -isystem ./include  -fPIC -g -DIN_LIBGCC2 -fbuilding-libgcc -fno-stack-protector -Dinhibit_libc -fPIC -I. -I. -I../../../.././gcc -I/home/user/ToolChain/riscv-gnu-toolchain/gcc/libgcc -I/home/user/ToolChain/riscv-gnu-toolchain/gcc/libgcc/. -I/home/user/ToolChain/riscv-gnu-toolchain/gcc/libgcc/../gcc -I/home/user/ToolChain/riscv-gnu-toolchain/gcc/libgcc/../include  -DHAVE_CC_TLS   -o _gcov_merge_add.o -MT _gcov_merge_add.o -MD -MP -MF _gcov_merge_add.dep -DL_gcov_merge_add -c /home/user/ToolChain/riscv-gnu-toolchain/gcc/libgcc/libgcov-merge.c
In file included from /home/user/ToolChain/Riscv_most_combinations/sysroot/usr/include/features.h:497,
                 from /home/user/ToolChain/Riscv_most_combinations/sysroot/usr/include/sys/mman.h:22,
                 from /home/user/ToolChain/riscv-gnu-toolchain/gcc/libgcc/libgcov.h:49,
                 from /home/user/ToolChain/riscv-gnu-toolchain/gcc/libgcc/libgcov-merge.c:26:

Riscv_most_combinations/sysroot/usr/include/gnu/stubs.h:8:11: fatal error: gnu/stubs-ilp32.h: No such file or directory
    8 | # include <gnu/stubs-ilp32.h>
      |           ^~~~~~~~~~~~~~~~~~~
compilation terminated.
make[4]: *** [Makefile:921: _gcov_merge_add.o] Error 1
make[4]: Leaving directory '/home/user/ToolChain/riscv-gnu-toolchain/build-gcc-linux-stage1/riscv64-unknown-linux-gnu/lib32/ilp32/libgcc'
make[3]: *** [Makefile:1211: multi-do] Error 1
make[3]: Leaving directory '/home/user/ToolChain/riscv-gnu-toolchain/build-gcc-linux-stage1/riscv64-unknown-linux-gnu/libgcc'
make[2]: *** [Makefile:127: all-multi] Error 2
make[2]: Leaving directory '/home/user/ToolChain/riscv-gnu-toolchain/build-gcc-linux-stage1/riscv64-unknown-linux-gnu/libgcc'
make[1]: *** [Makefile:12946: all-target-libgcc] Error 2
make[1]: Leaving directory '/home/user/ToolChain/riscv-gnu-toolchain/build-gcc-linux-stage1'
make: *** [Makefile:393: stamps/build-gcc-linux-stage1] Error 2

I think this error occured when compiling for -march=rv32imac -mabi=ilp32

Then I checked the linux gcc

./riscv64-unknown-linux-gnu-gcc --print-multi-lib
.;
lib32/ilp32;@march=rv32imac@mabi=ilp32
lib32/ilp32d;@march=rv32imafdc@mabi=ilp32d
lib64/lp64;@march=rv64imac@mabi=lp64
TommyMurphyTM1234 commented 5 months ago

--with-multilib-generator only works for a bare-metal toolchain build, not for Linux.

--with-multilib-generator= can specify what multilibs to build. The argument is a semicolon separated list of values, possibly consisting of a single value. Currently only supported for riscv*--elf. The accepted values and meanings are given below.

It used to be possible to alter the set of multilibs built by a Linux toolchain by editing gcc/config/riscv/t-linux-multilib but last time I tried that it no longer worked and I couldn't find any way to build a custom set of multilibs for a Linux toolchain.

I could only build the Linux toolchain with the default set of multilibs.

TommyMurphyTM1234 commented 5 months ago

Also - this error may not be related to the multilib issues:

fatal error: gnu/stubs-ilp32.h: No such file or directory

I've seen it happen when make distclean was not done between make (to build the bare-metal toolchain) and make linux (to build the Linux toolchain).

rajsureshgeorge commented 5 months ago

So is there anyway I can compile Linux gcc with that much extensions? @TommyMurphyTM1234

TommyMurphyTM1234 commented 5 months ago

So is there anyway I can compile Linux gcc with that much extensions? @TommyMurphyTM1234

What do you mean by "that much extensions"? Do you actually mean "that many multilibs"? I.e. a larger set of multilibs than the default set enabled for the Linux toolchain by configure ... -enable-multilib? Unfortunately, as per the issue link that I posted above, the last time I checked I wasn't able to override the default set and nobody else has responded to that issue to explain if/how that is possible these days.

TommyMurphyTM1234 commented 5 months ago

Just to summarise - I have been unable to identify any way to customise the set of multilibs built by the Linux toolchain build. I tried the following but none of them work and the toolchain simply gets built with the default set of multilibs:

  1. Use configure ... --with-multilib-generator=.... Doesn't work because, as documented in the readme, this is for the bare-metal toolchain only.
  2. Edit gcc/config/riscv/t-linux-multilib (or regenerate it using gcc/config/riscv/multilib-generator) to specify the custom set of multilibs. This used to work in the past but at some stage (last year?) changes to the repo caused it top stop working
  3. Edit the generated Makefile to specify a different set of multilibs via GLIBC_MULTILIB_NAMES but these changes seem to be ignored and the default set of multilibs is still built regardless.
  4. I don't know if the configure ... --with-extra-multilib-test=... option is of any use/relevance here but I don't really understand it and the readme documentation on it is difficult to follow. I suspect that it's only relevant to testing and not the actual multibs that get bundled with the built toolchain?

I don't know of any other options for building a custom set of multilibs for the Linux toolchain unfortunately. Does anybody else? @cmuellner or @kito-cheng perhaps?

rajsureshgeorge commented 5 months ago

Thanks for the quick and helpful reponse. @TommyMurphyTM1234. I did tried with --enable-multilib and still getting the same error as ilp32.h: No such file or directory Did use this ./configure --prefix=/home/user/Riscv_most_combinations --enable-multilib --with-cmodel=medany for configuring and then make linux Do I need to change the directory and make a new build?

TommyMurphyTM1234 commented 5 months ago

Thanks for the quick and helpful reponse. @TommyMurphyTM1234. I did tried with --enable-multilib and still getting the same error as ilp32.h: No such file or directory

Did you actually mean:

error: gnu/stubs-ilp32.h: No such file or directory

Did use this ./configure --prefix=/home/user/Riscv_most_combinations --enable-multilib --with-cmodel=medany for configuring and then make linux Do I need to change the directory and make a new build?

Are you sure that you're doing a clean build as I mentioned here:

For example if you do make [newlib] and subsequently do make linux then you should probably do make distclean in between the two builds - and optionally rm -rf <toolchain-install-dir> unless you use a different install directory each time or actually want to "merge" toolchain builds into one installation directory.

If that doesn't help then please detail all steps from start to finish that are needed to reproduce your error. I.e. everything from the initial git clone through all intermediate steps until the final make linux which triggers the error.

I have run the following many times without any such error:

git clone https://github.com/riscv-collab/riscv-gnu-toolchain
cd riscv-gnu-toolchain
./configure --prefix=`pwd`/installed-tools --enable-multilib
make linux
TommyMurphyTM1234 commented 5 months ago

For example if you do make [newlib] and subsequently do make linux then you should probably do make distclean in between the two builds

TommyMurphyTM1234 commented 5 months ago

FWIW I just did this and it worked fine (I just used --disable-gdb to reduce the build time):

git clone https://github.com/riscv-collab/riscv-gnu-toolchain
cd riscv-gnu-toolchain
./configure --prefix=`pwd`/installed-tools --disable-gdb --enable-multilib --with-cmodel=medany
make linux

So if that fails for you then it is most likely due to a previous build or something else in your environment.

rajsureshgeorge commented 5 months ago

@TommyMurphyTM1234 Why is it not possible to build using this configuration? ./configure --prefix=/home/ToolChain/RISCV_RV32IMAFC/ --with-cmodel=medany --with-arch=rv32imafc --with-abi=ilp32f then make linux

checking whether this-is-not-the-compiler-youre-looking-for can link programs... no
checking for sysdeps preconfigure fragments... aarch64 alpha arc arm csky hppa i386 m68k microblaze checking for grep that handles long lines and -e... /usr/bin/grep
checking for egrep... /usr/bin/grep -E
mips nios2 powerpc riscv glibc does not yet support systems with the F but not D extensions
make: *** [Makefile:363: stamps/build-glibc-linux-rv32imafc-ilp32f] Error 1

Do you have any list showing the possible configurations for --with-arch and --with-abi?? and also Is there any way I can build linux with this configuration -march=rv32imafc -mabi=ilp32 and also all the other available combinations? Since Linux Toolchain only support the --enable-multilib and not the --with-multilib tags

TommyMurphyTM1234 commented 5 months ago

@TommyMurphyTM1234 Why is it not possible to build using this configuration? ./configure --prefix=/home/ToolChain/RISCV_RV32IMAFC/ --with-cmodel=medany --with-arch=rv32imafc --with-abi=ilp32f then make linux

checking whether this-is-not-the-compiler-youre-looking-for can link programs... no
checking for sysdeps preconfigure fragments... aarch64 alpha arc arm csky hppa i386 m68k microblaze checking for grep that handles long lines and -e... /usr/bin/grep
checking for egrep... /usr/bin/grep -E
mips nios2 powerpc riscv glibc does not yet support systems with the F but not D extensions
make: *** [Makefile:363: stamps/build-glibc-linux-rv32imafc-ilp32f] Error 1

The error message is literally telling you why!

mips nios2 powerpc riscv glibc does not yet support systems with the F but not D extensions

Glibc requires the RISC-V D extension in order to build right now. Presumably enabling it to build with just F would require work to be done upstream in the Glibc project.

TommyMurphyTM1234 commented 5 months ago

Is there any way I can build linux with this configuration -march=rv32imafc -mabi=ilp32

Not a Linux/Glibc toolchain anyway for the reason mentioned above. Maybe a Linux/Musl toolchain might allow it?

and also all the other available combinations?

What specifically do you mean by "all other available combinations"? I've already explained some of the issues that militate against building any arbitrary set of multilibs for the Linux toolchain.

As far as I can see if you can't build separate toolchains for each arch/abi that you need to use, the ABIs in question don't include the D extension (for Glibc), and if you really need to build a Linux toolchain with a custom set of multilibs then ... you're stuck.