From 91d27868951a31d482c8e0ac74a67bcc2e3c5614 Mon Sep 17 00:00:00 2001 From: Lephenixnoir Date: Sun, 21 Aug 2022 11:23:53 +0200 Subject: [PATCH] manual install tutorial --- README.md | 116 ++++++++++++++++++++++++++++++------------------------ 1 file changed, 65 insertions(+), 51 deletions(-) diff --git a/README.md b/README.md index abb1da0..2927216 100644 --- a/README.md +++ b/README.md @@ -12,6 +12,7 @@ The most common way to install this compiler is for the fxSDK, and it can be aut ```bash % giteapc install Lephenixnoir/sh-elf-gcc +# After you install the libc, do it again ``` This installs GCC (and binutils if missing) in the fxSDK's SuperH system root. Note that at first it will *not* install the C++ standard library libstdc++, because it requires the C standard library which is not available at this stage. After you install [fxlibc](/Vhex-Kernel-Core/fxlibc/) you should run GiteaPC's install command again, and this time the scripts will build libstdc++. The GiteaPC tutorial has more detailed instructions about this two-stage process. @@ -44,70 +45,83 @@ Follow the same procedure as for binutils; preferably use the same `PREFIX`. ## Method 3: Fully manually -TODO: Manual install tutorial and link to the Planète Casio one +First here is the [guide for installing GCC](https://gcc.gnu.org/install/index.html) and here is [the one for libstdc++](https://gcc.gnu.org/onlinedocs/libstdc++/manual/setup.html). -TODO: The stuff below about libstdc++ is outdated, we can now build the entire thing +Get your GCC version of choice from [gcc.gnu.org](https://ftp.gnu.org/gnu/gcc/) and extract the archive. -**Notes on building libstdc++-v3** +**Warning:** GCC 12.1 and GCC 12.2 on your host computer (ie. the one you see with `gcc --version`) has a [critical bug](https://gcc.gnu.org/bugzilla/show_bug.cgi?id=106609) which causes it to incorrectly compile sh-elf-gcc starting from version 12. If your host GCC is version 12.1 or 12.2, stick to version 11.1 for the SuperH compiler. -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). +If using GCC 11.1 (or possibly earlier) for the SuperH compiler, we need to patch the libstdc++ configure script because it tries to run tests that are too advanced for our setup and not actually intended to run on cross-compilers. GCC 12 has this patch upstream. -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" +```bash +% patch -u -N -p0 < patches/gcc-11.1.0-libstdc++-v3-skip-dlopen.patch ``` -* `--enable-clocale=generic`: We want minimal locales and this is certainly the minimalistic option. -* `--enable-libstdcxx-allocator`: `=malloc` might be an option too. +Also download prerequisites if you don't have them system-wide. + +```bash +% cd gcc-$VERSION +% ./contrib/download_prerequisites +% cd .. +``` + +Now choose a prefix for install. If you're installing for the fxSDK, you must use `$(fxsdk path sysroot)`, otherwise anything that is isolated from the native OS is fine. + +```bash +% SYSROOT="$(fxsdk path sysroot)" +``` + +Because the binutils is called `sh-elf-` and not `sh3eb-elf-`, GCC won't find it on PATH alone. Symlink them to `$SYSROOT/sh3eb-elf/bin`: + +```bash +% mkdir -p "$SYSROOT/sh3eb-elf/bin" +% for TOOL in as ld ar ranlib; do \ + ln -sf $(command -v sh-elf-$TOOL) "$SYSROOT/sh3eb-elf/bin/$TOOL" \ + done +``` + +You can then configure and build GCC. + +```bash +% mkdir build && cd build +% ../gcc-$VERSION/configure \ + --prefix="$SYSROOT" \ + --target="sh3eb-elf" \ + --with-multilib-list="m3,m4-nofpu" \ + --enable-languages="c,c++" \ + --without-headers \ + --program-prefix="sh-elf-" \ + --enable-libssp \ + --enable-lto \ + --enable-clocale="generic" \ + --enable-libstdcxx-allocator \ + --disable-threads \ + --disable-libstdcxx-verbose \ + --enable-cxx-flags="-fno-exceptions" +``` + +* `--without-headers`: Also indicates a cross-compiler in many scenarios. +* `--enable-clocale="generic"`: Makes it easier to build the libstdc++. +* `--enable-libstdcxx-allocator`: Same; `=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. +* `--disable-libstdcxx-verbose`: For space; we don't always have stderr anyway. +* `--enable-cxx-flags="-fno-exceptions"`: Unless you have a kernel with exception support I guess. -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. +Then build and install gcc. -Now build and install that GCC and the libgcc. - -``` +```bash % make -j$(nproc) all-gcc all-target-libgcc -% make -j$(nproc) install-strip-gcc install-strip-target-libgcc +% make 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. +The next step is to install the libc. The standard fxSDK setup is to install [OpenLibm](https://gitea.planet-casio.com/Lephenixnoir/OpenLibm) and [fxlibc](https://gitea.planet-casio.com/Vhex-Kernel-Core/fxlibc/). Feel free to experiment. Make sure the includes and libraries end up in `$SYSROOT/sh3eb-elf/{bin,include}` since this is where GCC looks in hosted-like situations. -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). +Once the libc is available we can come back to GCC's build folder and actually compile libstdc++. -``` -% 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. - -``` +```bash +# Install the libc, then: +% make -j$(nproc) all-target-libstdc++-v3 % make install-strip-target-libstdc++-v3 ``` + +You can then clean up the source archive, source files, and build folder if needed. Link add-ins with `-lm -lstdc++ -lc -lgcc` in this order for the best results.