#!/usr/bin/bash COMPILER_DIR="${PWD}/compiler" DOWNLOAD_DIR="${COMPILER_DIR}/download" SOURCES_DIR="${COMPILER_DIR}/sources" BUILD_DIR="${COMPILER_DIR}/build" GCC_VER=10.2.0 GCC_TAR_FILE="gcc-${GCC_VER}.tar.xz" GCC_TAR_URL="https://ftp.gnu.org/gnu/gcc/gcc-${GCC_VER}/${GCC_TAR_FILE}" GCC_SOURCE="${SOURCES_DIR}/gcc-${GCC_VER}" GCC_BUILD="${BUILD_DIR}/gcc-${GCC_VER}" BINUTILS_VER=2.36 BINUTILS_TAR_FILE="binutils-${BINUTILS_VER}.tar.xz" BINUTILS_TAR_URL="https://ftp.gnu.org/gnu/binutils/${BINUTILS_TAR_FILE}" BINUTILS_SOURCE="${SOURCES_DIR}/binutils-${BINUTILS_VER}" BINUTILS_BUILD="${BUILD_DIR}/binutils-${BINUTILS_VER}" TARGET_COMPILER="${COMPILER_DIR}/target" export MAKEFLAGS="-j$(nproc)" export PREFIX="${TARGET_COMPILER}" export TARGET=i686-elf export PATH="${PREFIX}/bin:${PATH}" function log() { echo "$*" } function yes_or_no() { while true; do read -p "$* [y/n]: " yn case $yn in [Yy]*) return 0 ;; [Nn]*) echo "Aborted" return 1 ;; esac done } function download() { if [ -f "${DOWNLOAD_DIR}/$2" ]; then log "Not downloading $2" return 0 fi log "Downloading $2" curl -o "${DOWNLOAD_DIR}/$2" "$1" } function extract_source() { if [ -d "$1" ]; then log "already extracted $2, skipping" return 0 fi log "Extracting $2" tar -C "${SOURCES_DIR}" -xf "${DOWNLOAD_DIR}/$2" } function ensure_dir() { if [ ! -d "$1" ]; then mkdir -p "$1" fi } # Verify if [ -d "${COMPILER_DIR}" ]; then if ! yes_or_no "Do you want to rebuild?"; then exit 1 fi fi # Download sources ensure_dir "${COMPILER_DIR}" ensure_dir "${DOWNLOAD_DIR}" ensure_dir "${TARGET_COMPILER}" ensure_dir "${BUILD_DIR}" ensure_dir "${GCC_BUILD}" ensure_dir "${BINUTILS_BUILD}" download "${GCC_TAR_URL}" "${GCC_TAR_FILE}" download "${BINUTILS_TAR_URL}" "${BINUTILS_TAR_FILE}" extract_source "${GCC_SOURCE}" "${GCC_TAR_FILE}" extract_source "${BINUTILS_SOURCE}" "${BINUTILS_TAR_FILE}" # Build function build_binutils() { pushd . || return 1 cd "${BINUTILS_BUILD}" || return 1 "${BINUTILS_SOURCE}/configure" --target=${TARGET} --prefix=${PREFIX} --with-sysroot --disable-nls --disable-werror || return 1 make || return 1 make install || return 1 popd || return 1 return 0 } function build_gcc() { if ! which -- "${TARGET}-as"; then log "Could not find ${TARGET}-as!" return 1 fi pushd . || return 1 cd "${GCC_BUILD}" || return 1 "${GCC_SOURCE}/configure" --target=${TARGET} --prefix=${PREFIX} --disable-nls --enable-languages=c --without-headers || return 1 make all-gcc || return 1 make all-target-libgcc || return 1 make install-gcc || return 1 make install-target-libgcc || return 1 popd || return 1 return 0 } if ! build_binutils; then log "Failed to build binutils!" exit 1 fi if ! build_gcc; then log "Failed to build binutils!" exit 1 fi