# Automatic `sh-elf-gcc` installer This script can be used to automatically compile and install a GCC cross-compiler targeting SH3 and SH4 calculators. The normal use is with GiteaPC: ``` % giteapc install Lephenixnoir/sh-elf-gcc ``` You can also install manually. First install [`sh-elf-binutils`](https://gitea.planet-casio.com/Lephenixnoir/sh-elf-binutils), then run the GiteaPC Makefile with a manually-specified install prefix: ``` % make -f giteapc.make configure build install PREFIX=$HOME/.local ``` An `any` configuration is provided in case GCC is already installed externally, to have this package installed without rebuilding it. ``` % giteapc install Lephenixnoir/sh-elf-gcc:any ``` ## Notes on building libstdc++-v3 These are experimental notes on attempts at building the C++ standard library implementation bundled with GCC, `libstdc++-v3`. For the official manual, see [libstdc++ info manual, Chapter 2: Setup](https://gcc.gnu.org/onlinedocs/libstdc++/manual/setup.html) (gcc.gnu.org). So far, I was only able to build the **free-standing subset** which has basically nothing in it, see [Freestanding and hosted implementations](https://en.cppreference.com/w/cpp/freestanding) (cppreference.com). As a rule of thumb only features that look like extensions of the language are supported in there (RTTI, exceptions, coroutines, etc.) and everything that looks like a library (STL containers, I/O tools, filesystem) you can forget about. This subset does not include familiar features but it is needed nonetheless for C++ programs to work at all. So how do we go around doing that? First configure GCC as usual (follow `configure.sh`), but use a separate build folder. Since this is experimental the files are likely to stay here longer while debugging and you don't want them gone during a GCC upgrade. There are a couple of additional flags to care about, mainly described [here](https://gcc.gnu.org/onlinedocs/libstdc++/manual/configure.html). ``` % export PREFIX="$(pwd)" % mkdir build-libstdc++ % cd build-libstdc++ % ../gcc-11.1.0/configure --prefix="$PREFIX" --target=sh3eb-elf --with-multilib-list=m3,m4-nofpu --enable-languages=c,c++ --without-headers --with-newlib --program-prefix=sh-elf- --enable-libssp --enable-lto --enable-clocale=generic --enable-libstdcxx-allocator --disable-threads --disable-hosted-libstdcxx --disable-libstdcxx-verbose --enable-cxx-flags="-ffreestanding -fno-exceptions" ``` * `--enable-clocale=generic`: We want minimal locales and this is certainly the minimalistic option. * `--enable-libstdcxx-allocator`: `=malloc` might be an option too. * `--disable-threads`: Obvious. * `--disable-hosted-libstdcxx`: This builds only the free-standing subset of the library. If you're adventurous, remove it. * `--disable-libstdcxx-verbose`: We don't have a systematic standard error stream anyway. * `--enable-cxx-flags="-ffreestanding -fno-exceptions"`: Everything should be free-standing since we don't use a standard runtime. Currently I don't know of a way to completely disable exceptions in a way that linking with libstdc++ does not include all the stack unwinding and RTTI code for exceptions, but it sure starts with `-fno-exceptions` so it can't hurt to have that. Now build and install that GCC and the libgcc. ``` % make -j$(nproc) all-gcc all-target-libgcc % make -j$(nproc) install-strip-gcc install-strip-target-libgcc ``` Next step is to install [OpenLibm](https://gitea.planet-casio.com/Lephenixnoir/OpenLibm) and [fxlibc](https://gitea.planet-casio.com/Vhex-Kernel-Core/fxlibc/) since we're certainly not going to build the C++ standard library without the C standard library. For some reason OpenLibm installs its headers in the `include/openlibm` subfolder, but then includes them as if they were in `include`, so we have to add a path. Normally either the projet provides that path, or gint does it through its CMake find module. Here we can symlink to the `sh3eb-elf/sys-include` folder in this repo's root folder (or `include` but it's already symlinked to the compiler's install folder and we don't really want to override that). ``` % SRC="$(sh-elf-gcc -print-file-name=include/openlibm)" % DST="../sh3eb-elf/sys-include" % mkdir -p "$DST" % for x in "$SRC"/*.h; do ln -s "$x" "$DST/${x#$SRC/}"; done ``` Also `` has issues because GCC only redirects to its default `"stdint-gcc.h"` when free-standing, which conftest programs are not, so we have to provide some version of ``. ``` % echo '#include "stdint-gcc.h"' > ../sh3eb-elf/sys-include/stdint.h ``` After this, come back to the build folder, run the build command for libstdc++-v3, and hope it works out. I recommend not using `-j` as it makes error messages and logs more linear, and the library builds very fast anyway. ``` % make all-target-libstdc++-v3 ``` If it fails, check out `sh3eb-elf/libstdc++-v3/config.log` for configure errors, or other log files if you make it past the configuration step. `config.log` has many details on programs that failed to compile; not all failures to build are fatal for the configuration step, but some are. If it succeeds, install. ``` % make install-strip-target-libstdc++-v3 ``` ### Current problems Hard problems: * None. The free-standing subset compiles. Things that look like they could be involved in problems: * Anything that is not in the fxlibc can fail to link. * The conftest programs are built without `-ffreestanding`, which means autoconf cannot really link stuff. This is probably not too much of a problem, because it's cross-compiled anyway so there's nothing to do with a linked program, but who knows. * autoconf compiles conftest programs as if on a fully-featured dynamic OS, which is nowhere near true (eg. it builds with `-shared-libgcc`).