Skip to content

Instantly share code, notes, and snippets.

@badcf00d
Last active May 21, 2024 12:54
Show Gist options
  • Save badcf00d/2f6054441375d9c94896aaa8e878ab4f to your computer and use it in GitHub Desktop.
Save badcf00d/2f6054441375d9c94896aaa8e878ab4f to your computer and use it in GitHub Desktop.
Build arm-none-eabi-gcc cross-compiler
#!/bin/bash
set -e
set -v
# Install prerequisites
sudo apt-get -y install gcc \
libgmp-dev \
libmpfr-dev \
libmpc-dev \
libisl-dev \
libzstd-dev \
libexpat-dev \
liblzma-dev \
libsource-highlight-dev \
libpython3-dev \
libbabeltrace-dev \
libncurses5-dev \
meson \
ninja-build \
texinfo \
pkg-config \
python3 \
python-is-python3 \
flex \
diffutils \
git \
bison \
file
# For mingw
# pacman -S mingw-w64-x86_64-toolchain mingw-w64-x86_64-mpc mingw-w64-x86_64-mpfr mingw-w64-x86_64-gmp mingw-w64-x86_64-meson mingw-w64-x86_64-ninja texinfo bison flex diffutils
# Setup build directory
PREFIX=$HOME/gcc-cross-compiler/build
mkdir -p $PREFIX
cd $PREFIX/..
# Clone repositories (may be wise to checkout specific versions i.e. latest release tag)
git clone --depth=1 -b releases/gcc-14.1.0 https://gcc.gnu.org/git/gcc.git
git clone --depth=1 -b newlib-4.4.0 https://sourceware.org/git/newlib-cygwin.git
git clone --depth=1 -b gdb-14.2-release https://sourceware.org/git/binutils-gdb.git
git clone --depth=1 -b 1.8.6 https://github.com/picolibc/picolibc.git
# Build binutils
cd $PREFIX/.. && mkdir -p binutils-build && cd binutils-build
../binutils-gdb/configure \
--target=arm-none-eabi \
--prefix=$PREFIX \
--with-pkgversion=my-custom-$(date -I) \
--with-sysroot \
--with-lzma \
--with-expat \
--with-python \
--with-isl \
--with-zstd \
--enable-ld=yes \
--enable-gold=no \
--enable-plugins \
--enable-multilib \
--enable-lto \
--enable-source-highlight \
--disable-werror \
--disable-nls \
--disable-warn-rwx-segments
make -j$(nproc)
make install
# Build gcc (state-1), this is so that our libc implementation below (newlib)
# gets compiled with the nice shiny new compiler version as well. This build
# will only build the gcc compiler itself, not all of the libraries like libgcc etc.
# because for that we need a libc implementation... which we haven't built yet.
#
# You could alternatively skip this step by installing a arm-none-eabi-gcc
# compiler from somewhere else (i.e. sudo apt install gcc-arm-none-eabi)
# and use that to compile newlib instead, which will probably work so long as
# it has been compiled with multilib support for at least rmprofile
# (because of the `--with-multilib-list=rmprofile` below)
cd $PREFIX/.. && mkdir -p gcc-stage1-build && cd gcc-stage1-build
../gcc/configure \
--prefix=$PREFIX \
--enable-languages=c \
--target=arm-none-eabi \
--with-pkgversion=stage1-my-custom-$(date -I) \
--with-isl \
--with-newlib \
--with-sysroot=$PREFIX/arm-none-eabi \
--with-multilib-list=rmprofile \
--without-headers \
--enable-lto \
--enable-multiarch \
--disable-libssp \
--disable-nls \
--disable-tls \
--disable-threads \
--disable-shared
make -j$(nproc) all-gcc
make install-gcc
export PATH=$PREFIX/bin:$PATH
# Build newlib using our stage1 compiler (this is essentially newlib-nano)
cd $PREFIX/.. && mkdir -p newlib-build && cd newlib-build
../newlib-cygwin/configure \
--target=arm-none-eabi \
--prefix=$PREFIX \
--disable-newlib-supplied-syscalls \
--disable-newlib-io-float \
--disable-newlib-io-long-double \
--disable-newlib-io-pos-args \
--disable-newlib-io-c99-formats \
--disable-newlib-io-long-long \
--disable-newlib-multithread \
--disable-newlib-retargetable-locking \
--disable-newlib-wide-orient \
--disable-newlib-fseek-optimization \
--disable-newlib-fvwrite-in-streamio \
--disable-newlib-unbuf-stream-opt \
--disable-newlib-atexit-dynamic-alloc \
--enable-newlib-nano-malloc \
--enable-newlib-nano-formatted-io \
--enable-newlib-global-atexit \
--enable-lite-exit \
--enable-newlib-reent-small \
--enable-libssp \
--enable-target-optspace
make -j$(nproc)
make install
# Don't care about building big and nano newlib, the one we just compiled is already "newlib-nano"
sed -ie "s/_nano//g" $PREFIX/arm-none-eabi/lib/nano.specs
# Build gcc (stage-2), this builds the whole gcc featureset,
# including the compiler, and all the gnu compiler libraries
cd $PREFIX/.. && mkdir -p gcc-build && cd gcc-build
../gcc/configure \
--prefix=$PREFIX \
--enable-languages=c,c++ \
--target=arm-none-eabi \
--with-pkgversion=my-custom-$(date -I) \
--with-newlib \
--with-sysroot=$PREFIX/arm-none-eabi \
--with-native-system-header-dir=/include \
--with-multilib-list=rmprofile \
--enable-lto \
--enable-target-optspace \
--enable-multiarch \
--disable-libssp \
--disable-nls \
--disable-tls \
--disable-threads \
--disable-shared
make -j$(nproc)
make install
# Build picolibc
cd $PREFIX/.. && mkdir -p picolibc-build && cd picolibc-build
../picolibc/scripts/do-configure arm-none-eabi \
-Dsysroot-install=true \
-Dfast-strcmp=false \
-Dio-c99-formats=false \
-Dnewlib-global-atexit=true \
-Dnewlib-multithread=false \
-Dnewlib-retargetable-locking=false
ninja
ninja install
# Delete the build directories if you want
# rm -rf $PREFIX/../binutils* $PREFIX/../gcc* $PREFIX/../newlib* $PREFIX/../picolibc*
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment