riscv-collab / riscv-gnu-toolchain

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

Libstdc++ Nano? #1228

Open toddsharpe opened 1 year ago

toddsharpe commented 1 year ago

When I build this toolchain locally (./configure --prefix=$INSTALL_DIR --with-arch=rv32i --with-cmodel=medlow --with-multilib-generator="rv32i-ilp32--;rv32ima-ilp32--") I notice in the output there are a few nano libs:

./riscv32-unknown-elf/lib/libm_nano.a
./riscv32-unknown-elf/lib/libc_nano.a
./riscv32-unknown-elf/lib/libgloss_nano.a
./riscv32-unknown-elf/lib/libg_nano.a

However, when comparing to my Arm toolchain:

./hard/librdimon_nano.a
./hard/libsupc++_nano.a
./hard/libstdc++_nano.a
./hard/libc_nano.a
./hard/libg_nano.a

Noticably, libstdc++_nano.a seems to not be built by RISCV toolchain and therefore my riscv binaries are larger than the stm ones as the full libcstd++ brings in exceptions and demangle. Is there a way to produce this build? (It also looks like nano.specs itself for riscv needs to be updated?).

Thanks!

TommyMurphyTM1234 commented 1 year ago

Looks like the nano C++ lib is not built alright. I can't see it in the released nightly (actually less frequent and more sporadic than that) releases:

I presume that this is an omission in the build scripts?

If you want a toolchain with this library then perhaps the xPack binary version from @ilg-ul might help?

Better still might be the picolibc build of the tools since picolibc looks very promising as a replacement for newlib/nano-newlib?

but, unfortunately, I'm not sure if that work was ever completed? Maybe @keith-packard could comment?

It also looks like nano.specs itself for riscv needs to be updated?

In what way exactly?

the full libcstd++ brings in exceptions and demangle

If you're using an embedded target then it normally makes sense to disable these and other (e.g. RTTI) options.

my riscv binaries are larger than the stm ones

It doesn't really make sense to compare the size of binaries for completely different target architectures/ISAs.

toddsharpe commented 1 year ago

Thanks for the reply @TommyMurphyTM1234!

I presume that this is an omission in the build scripts?

This was my thinking as well, it seems the ARM tools do this pass: https://github.com/ARM-software/toolchain-gnu-bare-metal/blob/master/build-toolchain.sh#L494-L499 and copy them: https://github.com/ARM-software/toolchain-gnu-bare-metal/blob/bcd60182260b887b9e798d3dbb67f8d3c0834a5a/build-common.sh#L201-L230. I'm still familiarizing myself with the build scripts here but would love to try to get a smaller libstdc++ out of this build, if theres a file I should be looking at.

In what way exactly?

I just meant the riscv nano specs don't seem to include a remap of libstdc++ like the arm one does:

%:replace-outfile(-lstdc++ -lstdc++_nano)

(https://github.com/bminor/newlib/blob/master/libgloss/arm/elf-nano.specs and https://github.com/bminor/newlib/blob/master/libgloss/riscv/nano.specs)

If you're using an embedded target then it normally makes sense to disable these and other (e.g. RTTI) options.

My code is being compiled with: -fno-exceptions -fno-rtti but I see all these other symbols being pulled in from the toolchain's libstdc++ when looking at the map file (like __cxa_throw, __cxa_begin_catch and __cxa_demangle (which is like 23Kb!). My belief is I need the actual libstdc++ to be compiled with no exceptions/RTTI (like the flags in the ARM script above does for their nano version) to get rid of these. Am I missing something?

It doesn't really make sense to compare the size of binaries for completely different target architectures/ISAs.

Sorry, I meant the % of the resulting text segment that is "my code" versus "library code" I noticed was very much higher for this toolchain than arm, which lead me to look at the map file to see why.

TommyMurphyTM1234 commented 1 year ago

My code is being compiled with: -fno-exceptions -fno-rtti but I see all these other symbols being pulled in from the toolchain's libstdc++ when looking at the map file (like __cxa_throw, __cxa_begin_catch and __cxa_demangle (which is like 23Kb!). My belief is I need the actual libstdc++ to be compiled with no exceptions/RTTI (like the flags in the ARM script above does for their nano version) to get rid of these. Am I missing something?

Does it make any difference if you use --gc-sections at link time?

But the key issue that you reported - i.e. that the riscv-gnu-toolchain does not build or bundle the nano versions of the newlib C++ libs - is a certainly a valid bug report.

ilg-ul commented 1 year ago

I'm not sure, and I cannot check this now, but the xPack scripts might build the nano version with some extra options for libstdc++ too in order to reduce the size. Or at least that was the intention.

ilg-ul commented 1 year ago

I checked and the xPack build scripts use -fno-exceptions when building the nano version.

You can give the xPack binaries a try and check if you get shorter applications.

As a side note, except for larger flash sizes, there is nothing wrong with carefully using exceptions in embedded C++ applications. By carefully I mean only for really catastrophic and non-recoverable cases when execution is anyway disrupted, and not for passing regular errors in time-critical code.