Skip to content

Instantly share code, notes, and snippets.

@mikalv
Created December 15, 2021 19:14
Show Gist options
  • Save mikalv/85c9a2eb0e04e122f7a6ca419a1d2881 to your computer and use it in GitHub Desktop.
Save mikalv/85c9a2eb0e04e122f7a6ca419a1d2881 to your computer and use it in GitHub Desktop.
musl-bootstrap.sh
#!/bin/bash
# This script builds a (hopefully) working gcc based cross compiler
# Update to latest stable release
BINUTILS_VERSION=2.27
GMP_VERSION=6.1.2
MPFR_VERSION=3.1.5
MPC_VERSION=1.0.3
ISL_VERSION=0.16.1
GCC_VERSION=6.3.0
MUSL_VERSION=1.1.16
if [ "$#" -ne 2 ]; then
printf "Usage: boostrap.sh <target> <path>\n"
exit 1
fi
# Store the arguments
TARGET=$1
PREFIX=$(readlink -f $2)
# Download sources
mkdir -p src && cd src
SRCDIR=$(readlink -f .)
wget -nc https://ftp.gnu.org/gnu/binutils/binutils-$BINUTILS_VERSION.tar.gz || { echo 'Failed to download binutils!'; exit 1; }
wget -nc https://ftp.gnu.org/gnu/gmp/gmp-$GMP_VERSION.tar.xz || { echo 'Failed to download gmp!'; exit 1; }
wget -nc https://ftp.gnu.org/gnu/mpfr/mpfr-$MPFR_VERSION.tar.gz || { echo 'Failed to download mpfr!'; exit 1; }
wget -nc https://ftp.gnu.org/gnu/mpc/mpc-$MPC_VERSION.tar.gz || { echo 'Failed to download mpc!'; exit 1; }
wget -nc ftp://gcc.gnu.org/pub/gcc/infrastructure/isl-$ISL_VERSION.tar.bz2 || { echo 'Failed to download isl!'; exit 1; }
wget -nc https://ftp.gnu.org/gnu/gcc/gcc-$GCC_VERSION/gcc-$GCC_VERSION.tar.gz || { echo 'Failed to download gcc!'; exit 1; }
wget -nc https://www.musl-libc.org/releases/musl-$MUSL_VERSION.tar.gz || { echo 'Failed to download musl!'; exit 1; }
# Setup path
PATH=$PREFIX/bin:$PATH
# Setup makeflags
MAKEFLAGS=-j$(($(nproc || { echo 'Command `nproc` not found!'; exit 1; }) + 1))
# Dirty hack to fix sysroot support
mkdir -p $PREFIX/$TARGET/include
ln -sf . $PREFIX/$TARGET/usr
# On amd64 create the lib64 symlink
case $(uname -m) in
x86_64) mkdir -p $PREFIX/$TARGET/lib && ln -sf lib $PREFIX/$TARGET/lib64 ;;
esac
# Build binutils
tar -xf binutils-$BINUTILS_VERSION.tar.gz || { echo 'Failed to extract binutils!'; exit 1; } && cd binutils-$BINUTILS_VERSION
mkdir -p build && cd build
../configure --prefix=$PREFIX --target=$TARGET --disable-multilib --with-sysroot=$PREFIX/$TARGET --disable-nls || { echo 'Binutils configure failed!'; exit 1; }
make $MAKEFLAGS || { echo 'Binutils compile failed!'; exit 1; }
make install || { echo 'Binutils install failed!'; exit 1; }
# Build gcc
cd $SRCDIR
tar -xf gcc-$GCC_VERSION.tar.gz || { echo 'Extracting gcc failed!'; exit 1; } && cd gcc-$GCC_VERSION
tar -xf ../gmp-$GMP_VERSION.tar.xz || { echo 'Extracting gmp failed!'; exit 1; } && mv gmp-$GMP_VERSION gmp
tar -xf ../mpfr-$MPFR_VERSION.tar.gz || { echo 'Extracting mpfr failed!'; exit 1; } && mv mpfr-$MPFR_VERSION mpfr
tar -xf ../mpc-$MPC_VERSION.tar.gz || { echo 'Extracting mpc failed!'; exit 1; } && mv mpc-$MPC_VERSION mpc
tar -xf ../isl-$ISL_VERSION.tar.bz2 || { echo 'Extracting isl failed!'; exit 1; } && mv isl-$ISL_VERSION isl
mkdir -p build && cd build
../configure --prefix=$PREFIX --target=$TARGET --enable-languages=c,c++ --disable-multilib --with-sysroot=$PREFIX/$TARGET \
--disable-nls --disable-decimal-float --disable-libatomic --disable-libgomp --disable-libmpx --disable-libquadmath --disable-libssp --disable-libvtv \
--disable-libsanitizer|| { echo 'Gcc configure failed!'; exit 1; }
# Build just the compiler for now
make $MAKEFLAGS all-gcc || { echo 'Building the compiler part of gcc failed!'; exit 1; }
make install-gcc || { echo 'Failed to install gcc!'; exit 1; }
# Build musl
cd $SRCDIR
tar -xf musl-$MUSL_VERSION.tar.gz || { echo 'Error extracting musl!'; exit 1; } && cd musl-$MUSL_VERSION
mkdir -p build && cd build
CROSS_COMPILE="$TARGET-" ../configure --prefix=/usr --disable-gcc-wrapper || { echo 'Failed to configure musl!'; exit 1; }
make DESTDIR=$PREFIX/$TARGET install-headers || { echo 'Failed to install musl headers!'; exit 1; }
ARCH=$(echo $TARGET | cut -d'-' -f 1)
make $MAKEFLAGS obj/crt/$ARCH/crti.o obj/crt/$ARCH/crtn.o || { echo ' Failed to build the C runtime!'; exit 1; }
cp obj/crt/$ARCH/crti.o $PREFIX/$TARGET/lib/ || { echo 'Failed to install the C runtime!'; exit 1; }
cp obj/crt/$ARCH/crtn.o $PREFIX/$TARGET/lib/ || { echo 'Failed to install the C runtime!'; exit 1; }
$TARGET-gcc -nostdlib -nostartfiles -shared -x c /dev/null -o $PREFIX/$TARGET/lib/libc.so || { echo 'Failed to install fake C library!'; exit 1; }
# Build libgcc
cd $SRCDIR/gcc-$GCC_VERSION/build
make $MAKEFLAGS all-target-libgcc || { echo 'Failed to build libgcc!'; exit 1; }
make install-target-libgcc || { echo 'Failed to install libgcc!'; exit 1; }
# Finish building musl
cd $SRCDIR/musl-$MUSL_VERSION/build
# Warning: musl must be reconfigured
CROSS_COMPILE="$TARGET-" ../configure --prefix=/usr --disable-gcc-wrapper || { echo 'Failed to re-configure musl!'; exit 1; }
make $MAKEFLAGS || { echo 'Failed to build musl!'; exit 1; }
make DESTDIR=$PREFIX/$TARGET install || { echo 'Failed to install musl!'; exit 1; }
# Finally build the rest of gcc
cd $SRCDIR/gcc-$GCC_VERSION/build
make $MAKEFLAGS || { echo 'Failed to build gcc!'; exit 1; }
make install || { echo 'Failed to install gcc'; exit 1; }
# Fix incomplete limits.h
cd $SRCDIR/gcc-$GCC_VERSION
cat gcc/limitx.h gcc/glimits.h gcc/limity.h > `dirname $($TARGET-gcc -print-libgcc-file-name)`/include-fixed/limits.h \
|| { echo 'Failed to create final limits.h!'; exit 1; }
echo 'Done building! Everything succeeded!'
exit 0
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment