sh-elf-gcc/README.md

5.9 KiB

SuperH toolchain: sh-elf-gcc

This repository provides scripts to automatically compile and install an SH3/SH4-compatible GCC cross-compiler. GCC is a collection of compilers most commonly used for C/C++.

The following three methods can be used to install the compiler with different levels of automation.

Note that this repository should usually be built twice: first to build the compiler, and then after the libc is installed to build the C++ library.

Method 1: Using GiteaPC

The most common way to install this compiler is for the fxSDK, and it can be automated with GiteaPC:

% 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 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.

A :any configuration is provided in case you already have another version of GCC installed in the fxSDK sysroot and want to keep using it (ie. skip a version upgrade). This will mark this repository as installed, so other repositories depending on it can build, without actually compiling binutils.

% giteapc install Lephenixnoir/sh-elf-gcc:any

A :clean configuration is also provided if you want to clean up the source and build files automatically after the second pass. This frees up some disk space.

% giteapc install Lephenixnoir/sh-elf-gcc:clean

Method 2: Manually running the scripts

Make sure to previously install:

Follow the same procedure as for binutils; preferably use the same PREFIX.

% make -f giteapc.make configure build install PREFIX="$HOME/.local"

Method 3: Fully manually

First here is the guide for installing GCC and here is the one for libstdc++.

Get your GCC version of choice from gcc.gnu.org and extract the archive.

Warning: GCC 12.1 and GCC 12.2 on your host computer (ie. the one you see with gcc --version) has a critical bug 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.

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.

% patch -u -N -p0 < patches/gcc-11.1.0-libstdc++-v3-skip-dlopen.patch

Also download prerequisites if you don't have them system-wide.

% 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.

% 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:

% 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.

% 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-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.

Then build and install gcc.

% make -j$(nproc) all-gcc all-target-libgcc
% make install-strip-gcc install-strip-target-libgcc

The next step is to install the libc. The standard fxSDK setup is to install OpenLibm and 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.

Once the libc is available we can come back to GCC's build folder and actually compile libstdc++.

# 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.