manual install tutorial

This commit is contained in:
Lephenixnoir 2022-08-21 11:23:53 +02:00
parent 26affe51cf
commit 91d2786895
No known key found for this signature in database
GPG key ID: 1BBA026E13FC0495

116
README.md
View file

@ -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 `<stdint.h>` 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 `<stdint.h>`.
```
% 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.