Last active
May 10, 2022 05:23
-
-
Save hamsham/cf168713eb90f8631cb1b47792ae0e1e to your computer and use it in GitHub Desktop.
A simple script to check-out and cross-compile GCC.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/env bash | |
set -euo pipefail | |
# This script follows the instructions for building GCC, from the GNU | |
# documentation here: https://gcc.gnu.org/install/index.html | |
# x86_64: x86_64-pc-linux-gnu | |
# ARM: arm-none-eabi-linux | |
# Aarch64: aarch64-linux-gnu | |
# Vocore2: mipsel-openwrt-linux-uclibc | |
GCC_RELEASE_LATEST=12.1.0 | |
BINUTILS_RELEASE_LATEST=2.38 | |
GLIBC_RELEASE_LATEST=2.35 | |
NEWLIB_RELEASE_LATEST=4.1.0 | |
CLOOG_RELEASE_LATEST=0.18.1 | |
GMP_RELEASE_LATEST=6.2.1 | |
ISL_RELEASE_LATEST=0.24 | |
MPC_RELEASE_LATEST=1.2.1 | |
MPFR_RELEASE_LATEST=4.1.0 | |
GCC_GIT_REPO=https://github.com/gcc-mirror/gcc.git | |
#GCC_GIT_REPO=git://gcc.gnu.org/git/gcc.git | |
BINUTILS_GIT_REPO=git://sourceware.org/git/binutils-gdb.git | |
INFRASTRUCTURE_BASE_URL=https://gcc.gnu.org/pub/gcc/infrastructure | |
GLIBC_FTP_URL=https://ftp.gnu.org/gnu/glibc | |
NEWLIB_FTP_URL=ftp://sourceware.org/pub/newlib | |
KERNEL_BASE_URL=https://mirrors.edge.kernel.org/pub/linux/kernel | |
BUILD_DIR_SUFFIX="staging" | |
NUM_THREADS=$(getconf _NPROCESSORS_ONLN) | |
function validate_version_trio() | |
{ | |
local objectName="$1" | |
local outputDelimeter="$2" | |
local versionStr=$(echo "$3" | sed -E 's/([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+).*/\1.\2.\3/g') | |
local re='^[0-9]+$' | |
local major=$(echo "$versionStr" | cut -d '.' -f 1) | |
local minor=$(echo "$versionStr" | cut -d '.' -f 2) | |
local patchVer=$(echo "$versionStr" | cut -d '.' -f 3) | |
if [[ -n $patchVer ]]; then | |
if ! [[ $major =~ $re && $minor =~ $re && $patchVer =~ $re ]]; then | |
echo "Unable to validate ${objectName} version $versionStr" >&2 | |
exit 1 | |
fi | |
echo "${major}${outputDelimeter}${minor}${outputDelimeter}${patchVer}" | |
else | |
if ! [[ $major =~ $re && $minor =~ $re ]]; then | |
echo "Unable to validate ${objectName} version $versionStr" >&2 | |
exit 1 | |
fi | |
echo "${major}${outputDelimeter}${minor}" | |
fi | |
} | |
function verify_prerequisites() | |
{ | |
# Required executables listed from step 2 of the online manual | |
echo "Checking for prerequisite build tools..." | |
function _check_exe() | |
{ | |
local exeName=$(which "$1" 2> /dev/null) | |
if [[ -z "$exeName" ]]; then | |
echo -e "Error: Unable to find $1." >&2 | |
exit 1 | |
fi | |
echo -e "\tFound $1: $exeName" | |
} | |
_check_exe wget | |
_check_exe gzip | |
_check_exe bzip2 | |
_check_exe tar | |
_check_exe awk | |
_check_exe perl | |
_check_exe make | |
_check_exe zstd | |
_check_exe autoconf | |
_check_exe automake | |
_check_exe git | |
_check_exe makeinfo | |
echo "" | |
} | |
function get_project_src_dir() | |
{ | |
local projectName="$1" | |
local projectVersion="$2" | |
echo "$projectName-$projectVersion" | |
} | |
function get_project_build_dir() | |
{ | |
local projectName="$1" | |
local projectVersion="$2" | |
echo "$projectName-${projectVersion}-${BUILD_DIR_SUFFIX}" | |
} | |
function get_staging_dir() | |
{ | |
local buildTarget="$1" | |
echo "${buildTarget}-staging" | |
} | |
function get_target_dir() | |
{ | |
local gccVersion="$1" | |
echo "${gccVersion}-target" | |
} | |
function get_sysroot_dir() | |
{ | |
local installPrefix="$1" | |
echo "${installPrefix}" | |
} | |
function get_prefix_dir() | |
{ | |
local installPrefix="$1" | |
echo "${installPrefix}" | |
} | |
function get_host_target_string() | |
{ | |
local sourceDir="$1" | |
local archGuess=$("$sourceDir"/config.sub $2) | |
echo "$archGuess" | |
} | |
function get_kernel_target_string() | |
{ | |
local targetName="$1" | |
local kernelArch=$(echo "$targetName" | cut -d '-' -f 1) | |
case "$kernelArch" in | |
i386) | |
kernelArch=x86 | |
;; | |
x86_64) | |
kernelArch=x86 | |
;; | |
arm) | |
kernelArch=armv | |
;; | |
aarch64) | |
kernelArch=arm64 | |
;; | |
ppc) | |
kernelArch=powerpc | |
;; | |
ppc64) | |
kernelArch=powerpc | |
;; | |
sparc) | |
kernelArch=sparc | |
;; | |
sparc64) | |
kernelArch=sparc | |
;; | |
mips) | |
kernelArch=mips | |
;; | |
mips64) | |
kernelArch=mips | |
;; | |
s390x) | |
kernelArch=s390 | |
;; | |
ia64) | |
kernelArch=ia64 | |
;; | |
*) | |
echo "Unable to determine architecture to build kernel headers (unsupported arch: ${kernelArch})" >&2 | |
exit 1 | |
;; | |
esac | |
echo "${kernelArch}" | |
} | |
function get_concurrency() | |
{ | |
if [[ $NUM_THREADS -gt 1 ]]; then | |
echo "$NUM_THREADS" | |
else | |
echo 1 | |
fi | |
} | |
function download_lib_deps() | |
{ | |
local gccVersion="$1" | |
local workingDir="$2" | |
local kernelVer="$3" | |
local glibcVer="$4" | |
local newlibVer="$5" | |
local gccSrcDir="$workingDir"/$(get_project_src_dir gcc "$gccVersion") | |
local kernelMajor=$(echo "$kernelVer" | cut -d '.' -f 1) | |
echo "Downloading infrastructure dependencies." | |
function _download_lib_dep() | |
{ | |
local libName="$1" | |
local libVer="$2" | |
local archiveType="$3" | |
local baseUrl="$4" | |
local outDir="${workingDir}/${libName}-${libVer}" | |
local archive="${libName}-${libVer}.${archiveType}" | |
local url="${baseUrl}/${archive}" | |
if [[ -f "${workingDir}/$archive" ]]; then | |
echo "Archive for ${libName} found. Skipping download." | |
else | |
echo "Downloading ${archive} to ${workingDir}" | |
wget -c --https-only "$url" -P "$workingDir" | |
fi | |
tar -C "$workingDir" -xvf "${workingDir}/${archive}" | |
} | |
if [[ -n $newlibVer ]]; then | |
_download_lib_dep newlib "$NEWLIB_RELEASE_LATEST" tar.gz "$NEWLIB_FTP_URL" | |
fi | |
if [[ -n $glibcVer ]]; then | |
_download_lib_dep glibc $GLIBC_RELEASE_LATEST tar.xz "$GLIBC_FTP_URL" | |
fi | |
_download_lib_dep linux "$kernelVer" tar.gz "${KERNEL_BASE_URL}/v${kernelMajor}.x" | |
_download_lib_dep gmp "$GMP_RELEASE_LATEST" tar.bz2 "${INFRASTRUCTURE_BASE_URL}" | |
_download_lib_dep isl "$ISL_RELEASE_LATEST" tar.bz2 "${INFRASTRUCTURE_BASE_URL}" | |
_download_lib_dep mpc "$MPC_RELEASE_LATEST" tar.gz "${INFRASTRUCTURE_BASE_URL}" | |
_download_lib_dep mpfr "$MPFR_RELEASE_LATEST" tar.bz2 "${INFRASTRUCTURE_BASE_URL}" | |
_download_lib_dep cloog "$CLOOG_RELEASE_LATEST" tar.gz "${INFRASTRUCTURE_BASE_URL}" | |
pushd "${gccSrcDir}" | |
sh ./contrib/download_prerequisites | |
popd | |
echo "" | |
} | |
function clone_gcc() | |
{ | |
local gccVersion="$1" | |
local workingDir="$2" | |
local binutilsVer="$3" | |
local gccBranch="releases/gcc-$gccVersion" | |
local gccSrcDir="$workingDir"/$(get_project_src_dir gcc "$gccVersion") | |
local binutilsSrcDir="$workingDir"/$(get_project_src_dir binutils "$binutilsVer") | |
mkdir -p "$workingDir" | |
if [[ -d "$gccSrcDir" ]]; then | |
pushd "$gccSrcDir" | |
set +e | |
git status 2>&1 > /dev/null | |
local exit_status=$? | |
set -e | |
popd | |
if [[ exit_status -ne 0 ]]; then | |
echo "A non-source-controlled directory is located at $gccSrcDir. Please remove this directory and try again." >&2 | |
exit 1 | |
fi | |
else | |
git clone --depth 1 --branch "$gccBranch" "$GCC_GIT_REPO" "$gccSrcDir" | |
fi | |
echo "Updating local GCC branch for $gccVersion" | |
pushd "$gccSrcDir" | |
git checkout -- . | |
git pull --rebase | |
popd | |
echo "" | |
echo "Cloning BinUtils $binutilsVer" | |
if [[ -d "$binutilsSrcDir" ]]; then | |
pushd "$binutilsSrcDir" | |
set +e | |
git status 2>&1 > /dev/null | |
local exit_status=$? | |
set -e | |
popd | |
if [[ exit_status -ne 0 ]]; then | |
echo "A non-source-controlled directory is located at $binutilsSrcDir. Please remove this directory and try again." >&2 | |
exit 1 | |
fi | |
else | |
git clone --branch "binutils-$binutilsVer" "$BINUTILS_GIT_REPO" "$binutilsSrcDir" | |
fi | |
echo "Updating local Binutils branch for $binutilsVer" | |
pushd "$binutilsSrcDir" | |
git checkout -- . | |
git pull --rebase origin "binutils-$binutilsVer" | |
popd | |
echo "" | |
} | |
function make_kernel_headers() | |
{ | |
local kernelVer="$1" | |
local workingDir="$2" | |
local installPrefix="$3" | |
local buildTarget="$4" | |
local kernelArch=$(get_kernel_target_string "$buildTarget") | |
local concurrency=$(get_concurrency) | |
make -C "${workingDir}/linux-${kernelVer}" -j${concurrency} clean | |
make -C "${workingDir}/linux-${kernelVer}" -j${concurrency} ARCH="$kernelArch" INSTALL_HDR_PATH="$installPrefix" CROSS_COMPILE="$buildTarget"- headers_install | |
} | |
function configure_binutils() | |
{ | |
local binutilsVersion="$1" | |
local gccVersion="$2" | |
local workingDir="$3" | |
local installPrefix="$4" | |
local buildHost="$5" | |
local buildTarget="$6" | |
local buildStage="$7" | |
local sourceDir="${workingDir}"/$(get_project_src_dir binutils "$binutilsVersion") | |
local buildDir="${workingDir}"/$(get_project_build_dir binutils "$binutilsVersion") | |
if [[ "$buildStage" -eq 1 ]]; then | |
local buildMachine="$buildHost" | |
local configFlags="" | |
else | |
local buildMachine="$buildTarget" | |
local configFlags="--with-gnu-ld --with-gnu-as" | |
fi | |
echo "Resolved host architecture '$buildHost' and target architecture '$buildTarget'" | |
mkdir -p "${buildDir}" | |
pushd "${buildDir}" | |
set +e | |
CFLAGS_FOR_TARGET='-O2 -fPIC' \ | |
CXXFLAGS_FOR_TARGET='-O2 -fPIC' \ | |
"$sourceDir"/configure \ | |
--prefix="$(get_prefix_dir "$installPrefix")" \ | |
--build="$buildHost" \ | |
--host="$buildMachine" \ | |
--target="$buildTarget" \ | |
--with-sysroot="$(get_sysroot_dir "$installPrefix")" \ | |
--disable-nls \ | |
--disable-werror \ | |
$configFlags | |
#--disable-multilib \ | |
local status=$? | |
set -e | |
popd | |
if [[ $status -ne 0 ]]; then | |
echo "An error occurred while compiling binutils." >&2 | |
exit 1 | |
fi | |
echo "" | |
} | |
function make_binutils() | |
{ | |
local binutilsVersion="$1" | |
local gccVersion="$2" | |
local workingDir="$3" | |
local buildDir="$workingDir"/$(get_project_build_dir binutils "$binutilsVersion") | |
local concurrency=$(get_concurrency) | |
make -C "${buildDir}" -j${concurrency} | |
make -C "${buildDir}" -j${concurrency} install | |
echo "" | |
} | |
function configure_gcc_cross() | |
{ | |
local gccVersion="$1" | |
local newlibVer="$2" | |
local workingDir="$3" | |
local installPrefix="$4" | |
local buildHost="$5" | |
local buildTarget="$6" | |
local buildStage="$7" | |
local finalCompilation="$8" | |
local sourceDir="${workingDir}"/$(get_project_src_dir gcc "$gccVersion") | |
local buildDir="${workingDir}"/$(get_project_build_dir gcc "$gccVersion") | |
local host_cflags="" | |
local host_cxxflags="" | |
local extraFlags="" | |
if [[ "$finalCompilation" -eq 0 ]]; then | |
extraFlags="--disable-shared --with-headers=${installPrefix}/include" | |
fi | |
if [[ $buildStage -eq 2 ]]; then | |
local extraFlags="$extraFlags --without-headers" | |
fi | |
if [[ -n "$newlibVer" ]]; then | |
local extraFlags="$extraFlags --with-newlib" | |
if [[ $buildStage -gt 1 ]]; then | |
host_cflags="-L$installPrefix/${buildTarget}/lib -lc -lnosys" | |
host_cxxflags="-L$installPrefix/${buildTarget}/lib -lc -lnosys" | |
fi | |
fi | |
echo "Resolved host architecture '$buildHost' and target architecture '$buildTarget'" | |
mkdir -p "${buildDir}" | |
pushd "${buildDir}" | |
set +e | |
CFLAGS_FOR_TARGET="-O2 -fPIC $host_cflags" \ | |
CXXFLAGS_FOR_TARGET="-O2 -fPIC $host_cxxflags" \ | |
"$sourceDir"/configure \ | |
$extraFlags \ | |
--prefix="$(get_prefix_dir "$installPrefix")" \ | |
--host="$buildHost" \ | |
--target="$buildTarget" \ | |
--with-sysroot="$(get_sysroot_dir "$installPrefix")" \ | |
--with-native-system-header-dir="/include" \ | |
--with-gnu-as \ | |
--with-gnu-ld | |
#--disable-multilib | |
local status=$? | |
set -e | |
popd | |
if [[ $status -ne 0 ]]; then | |
echo "An error occurred while compiling GCC." >&2 | |
exit 1 | |
fi | |
echo "" | |
} | |
function make_gcc_cross() | |
{ | |
local gccVersion="$1" | |
local workingDir="$2" | |
local installPrefix="$3" | |
local buildTarget="$4" | |
local buildStage="$5" | |
local buildDir="$workingDir"/$(get_project_build_dir gcc "$gccVersion") | |
local concurrency=$(get_concurrency) | |
if [[ $buildStage -eq 1 ]]; then | |
make -C "${buildDir}" -j${concurrency} all-gcc | |
make -C "${buildDir}" -j${concurrency} install-gcc | |
elif [[ $buildStage -eq 2 ]]; then | |
make -C "${buildDir}" -j${concurrency} all-target-libgcc | |
make -C "${buildDir}" -j${concurrency} install-target-libgcc | |
elif [[ $buildStage -eq 3 ]]; then | |
make -C "${buildDir}" -j${concurrency} | |
make -C "${buildDir}" -j${concurrency} install | |
else | |
echo "Unknown build stage '$buildStage'" >&2 | |
exit 1 | |
fi | |
echo "" | |
} | |
function make_glibc() | |
{ | |
local gccVersion="$1" | |
local kernelVer="$2" | |
local glibcVersion="$3" | |
local buildHost="$4" | |
local buildTarget="$5" | |
local installPrefix="$6" | |
local workingDir="$7" | |
local buildStage="$8" | |
local sourceDir="" | |
local buildDir="" | |
sourceDir="${workingDir}"/$(get_project_src_dir glibc "$glibcVersion") | |
buildDir="${workingDir}"/$(get_project_build_dir glibc "$glibcVersion") | |
mkdir -p "${buildDir}" | |
pushd "${buildDir}" | |
set +e | |
local status=0 | |
if [[ $buildStage -eq 1 ]]; then | |
CFLAGS="-O2 -fPIC -L${installPrefix}/lib -L${installPrefix}/lib64" \ | |
CXXFLAGS="O2 -fPIC -L${installPrefix}/lib -L${installPrefix}/lib64" \ | |
"$sourceDir"/configure \ | |
--prefix="/" \ | |
--build="$buildHost" \ | |
--host="$buildTarget" \ | |
--target="$buildTarget" \ | |
--enable-kernel="$kernelVer" \ | |
--with-headers="${installPrefix}/include" \ | |
--with-sysroot="$(get_sysroot_dir "$installPrefix")" \ | |
--disable-werror \ | |
--enable-add-ons \ | |
--disable-tests \ | |
libc_cv_forced_unwind=yes | |
#--disable-multilib \ | |
status=$? | |
fi | |
set -e | |
popd | |
if [[ $status -ne 0 ]]; then | |
echo "An error occurred while compiling libC." >&2 | |
exit 1 | |
fi | |
local concurrency=$(get_concurrency) | |
if [[ $buildStage -eq 1 ]]; then | |
make DESTDIR="${installPrefix}" -C "${buildDir}" install-bootstrap-headers=yes install-headers | |
make -C "${buildDir}" -j${concurrency} csu/subdir_lib | |
install "${buildDir}/csu/crt1.o" "${buildDir}/csu/crti.o" "${buildDir}/csu/crtn.o" "${installPrefix}/${buildTarget}/lib" | |
touch "${installPrefix}/include/gnu/stubs.h" | |
else | |
make DESTDIR="${installPrefix}" -C "${buildDir}" -j${concurrency} | |
make DESTDIR="${installPrefix}" -C "${buildDir}" -j${concurrency} install | |
echo "Done." | |
fi | |
echo "" | |
} | |
function make_newlib() | |
{ | |
local gccVersion="$1" | |
local newlibVersion="$2" | |
local buildHost="$3" | |
local buildTarget="$4" | |
local installPrefix="$5" | |
local workingDir="$6" | |
local buildStage="$7" | |
local sourceDir="" | |
local buildDir="" | |
sourceDir="${workingDir}"/$(get_project_src_dir newlib "$newlibVersion") | |
buildDir="${workingDir}"/$(get_project_build_dir newlib "$newlibVersion") | |
mkdir -p "${buildDir}" | |
pushd "${buildDir}" | |
set +e | |
local status=0 | |
if [[ $buildStage -eq 1 ]]; then | |
"$sourceDir"/configure \ | |
--prefix="$installPrefix" \ | |
--build="$buildHost" \ | |
--host="$buildHost" \ | |
--target="$buildTarget" \ | |
--with-sysroot="$(get_sysroot_dir "$installPrefix")" \ | |
--with-newlib \ | |
--enable-newlib-io-pos-args \ | |
--enable-newlib-io-c99-formats \ | |
--enable-newlib-register-fini \ | |
--enable-newlib-io-long-long \ | |
--enable-newlib-io-long-double \ | |
--enable-newlib-mb \ | |
--enable-newlib-iconv \ | |
--enable-newlib-multithread \ | |
--disable-nls \ | |
--disable-shared | |
#--disable-multilib | |
status=$? | |
fi | |
set -e | |
popd | |
if [[ $status -ne 0 ]]; then | |
echo "An error occurred while compiling libC." >&2 | |
exit 1 | |
fi | |
local concurrency=$(get_concurrency) | |
if [[ $buildStage -eq 1 ]]; then | |
make -C "${buildDir}" -j${concurrency} all | |
make -C "${buildDir}" -j${concurrency} install | |
echo "Done." | |
fi | |
echo "" | |
} | |
function make_dependency() | |
{ | |
local depVersion="$1" | |
local depName="$2" | |
local buildHost="$3" | |
local buildTarget="$4" | |
local installPrefix="$5" | |
local workingDir="$6" | |
local sourceDir="${workingDir}"/$(get_project_src_dir "$depName" "$depVersion") | |
local buildDir="${workingDir}"/$(get_project_build_dir "$depName" "$depVersion") | |
echo "Building dependency: $depName-$depVersion" | |
mkdir -p "${buildDir}" | |
pushd "${buildDir}" | |
set +e | |
local status=0 | |
CFLAGS="-O2 -fPIC" \ | |
CXXFLAGS="-O2 -fPIC" \ | |
"$sourceDir"/configure \ | |
--prefix="$(get_prefix_dir "$installPrefix")" \ | |
--build="$buildHost" \ | |
--host="$buildTarget" \ | |
--target="$buildTarget" | |
status=$? | |
set -e | |
popd | |
if [[ $status -ne 0 ]]; then | |
echo "An error occurred while compiling $depName." >&2 | |
exit 1 | |
fi | |
local concurrency=$(get_concurrency) | |
make -C "${buildDir}" -j${concurrency} | |
make -C "${buildDir}" -j${concurrency} install | |
echo "Done." | |
echo "" | |
} | |
function print_usage() | |
{ | |
echo "USAGE:" | |
echo -e "\t-h,--help Prints this message then exits." | |
echo -e "\t-r,--release Sets the release branch of GCC to clone from git using 'MAJOR.MINOR.PATCH'." | |
echo -e "\t-d,--directory Path of the top-level directory where GCC will be checked-out and built (defaults to the current working directory)." | |
echo -e "\t-p,--prefix Specifies the installation prefix (note: 'make install' must be run manually outside of this script)." | |
echo -e "\t--host Select between an x86, arm, or aarch64 host compiler." | |
echo -e "\t--target Select between an x86, arm, or aarch64 build target." | |
echo -e "\t--resolve-host Attempt to resolve the local host compiler toolchain based on '--host'." | |
echo -e "\t--resolve-target Attempt to resolve the output target's compiler toolchain name based on '--target'" | |
echo -e "\t-b,--binutils Compile binutils at version 'MAJOR.MINOR.PATCH'" | |
echo -e "\t-k,--kernel Specifies the Linux kernel version using 'MAJOR.MINOR.PATCH'" | |
echo "" | |
} | |
function main() | |
{ | |
local releaseVer="$GCC_RELEASE_LATEST" | |
local binutilsVer="$BINUTILS_RELEASE_LATEST" | |
local workingDir="$(pwd)" | |
local hostArch="$(uname -m)-pc-linux-gnu" | |
local targetArch="$(uname -m)-pc-linux-gnu" | |
local kernelVer=$(uname --kernel-release | sed -E 's/([[:digit:]]+)\.([[:digit:]]+)\.([[:digit:]]+).+/\1.\2.\3/g') | |
local kernelArch=$(get_kernel_target_string "$targetArch") | |
local glibcVer="" | |
local newlibVer="" | |
local prefix="/opt" | |
local resolveHost=0 | |
local resolveTarget=0 | |
set +u | |
while [ -n "$1" ]; do | |
case "$1" in | |
-h | --help) | |
print_usage | |
exit | |
;; | |
-r | --release) | |
shift | |
releaseVer="$1" | |
;; | |
-b | --binutils) | |
shift | |
binutilsVer="$1" | |
;; | |
-d | --directory) | |
shift | |
workingDir="$1" | |
;; | |
-p | --prefix) | |
shift | |
prefix="$1" | |
;; | |
-g | --glibc) | |
shift | |
glibcVer="$1" | |
;; | |
-n | --newlib) | |
shift | |
newlibVer="$1" | |
;; | |
--host) | |
shift | |
hostArch="$1" | |
;; | |
--target) | |
shift | |
targetArch="$1" | |
;; | |
-k | --kernel) | |
shift | |
kernelVer="$1" | |
;; | |
--resolve-host) | |
resolveHost=1 | |
;; | |
--resolve-target) | |
resolveTarget=1 | |
;; | |
*) | |
echo "Unknown parameter '$1'" >&2 | |
print_usage | |
exit 1 | |
;; | |
esac | |
shift | |
done | |
set -u | |
if [[ -n "$glibcVer" && -n "$newlibVer" ]]; then | |
echo "Cannot have both Glibc and Newlib specified. You must choose only one." >&2 | |
exit 1 | |
fi | |
if [[ -z "$glibcVer" && -z "$newlibVer" ]]; then | |
glibcVer="$GLIBC_RELEASE_LATEST" | |
fi | |
if [[ -n "$glibcVer" ]]; then | |
glibcVer=$(validate_version_trio "Glibc" '.' "$glibcVer") | |
else | |
newlibVer=$(validate_version_trio "Newlib" '.' "$newlibVer") | |
fi | |
kernelVer=$(validate_version_trio "Linux kernel" '.' "$kernelVer") | |
binutilsVer=$(validate_version_trio "Binutils" '_' "$binutilsVer") | |
releaseVer=$(validate_version_trio "GCC" '.' "$releaseVer") | |
kernelArch=$(get_kernel_target_string "$targetArch") | |
local sourceDir=$(get_project_src_dir gcc "$releaseVer") | |
if [[ $resolveHost -ne 0 ]]; then | |
hostArch=$(get_host_target_string "$sourceDir" "$hostArch") | |
fi | |
if [[ $resolveTarget -ne 0 ]]; then | |
targetArch=$(get_host_target_string "$sourceDir" "$targetArch") | |
fi | |
echo "Compiling GCC version ${releaseVer} (Binutils ${binutilsVer}) for kernel ${kernelVer} (${kernelArch})." | |
local stagingDir="${workingDir}/$(get_staging_dir $targetArch)" | |
local targetDir="${workingDir}/$(get_target_dir $targetArch)" | |
verify_prerequisites | |
clone_gcc "$releaseVer" "$workingDir" "$binutilsVer" | |
download_lib_deps "$releaseVer" "$workingDir" "$kernelVer" "$glibcVer" "$newlibVer" | |
local oldPath="$PATH" | |
export PATH="$PATH:${stagingDir}/${targetArch}/bin:${stagingDir}/bin" | |
BUILD_DIR_SUFFIX="staging" | |
make_kernel_headers "$kernelVer" "$workingDir" "$stagingDir" "$targetArch" | |
configure_binutils "$binutilsVer" "$releaseVer" "$workingDir" "$stagingDir" "$hostArch" "$targetArch" 1 | |
make_binutils "$binutilsVer" "$releaseVer" "$workingDir" | |
configure_gcc_cross "$releaseVer" "$newlibVer" "$workingDir" "$stagingDir" "$hostArch" "$targetArch" 1 0 | |
make_gcc_cross "$releaseVer" "$workingDir" "$stagingDir" "$targetArch" 1 | |
if [[ -n "$glibcVer" ]]; then | |
make_glibc "$releaseVer" "$kernelVer" "$glibcVer" "$hostArch" "$targetArch" "$stagingDir" "$workingDir" 1 | |
else | |
make_newlib "$releaseVer" "$newlibVer" "$hostArch" "$targetArch" "$stagingDir" "$workingDir" 1 | |
fi | |
configure_gcc_cross "$releaseVer" "$newlibVer" "$workingDir" "$stagingDir" "$hostArch" "$targetArch" 2 0 | |
make_gcc_cross "$releaseVer" "$workingDir" "$stagingDir" "$targetArch" 2 | |
if [[ -n "$glibcVer" ]]; then | |
make_glibc "$releaseVer" "$kernelVer" "$glibcVer" "$hostArch" "$targetArch" "$stagingDir" "$workingDir" 2 | |
fi | |
configure_gcc_cross "$releaseVer" "$newlibVer" "$workingDir" "$stagingDir" "$hostArch" "$targetArch" 3 0 | |
make_gcc_cross "$releaseVer" "$workingDir" "$stagingDir" "$targetArch" 3 | |
export AR="${stagingDir}/bin/${targetArch}-ar" | |
export AS="${stagingDir}/bin/${targetArch}-as" | |
export CPP="${stagingDir}/bin/${targetArch}-cpp" | |
export CXX="${stagingDir}/bin/${targetArch}-g++" | |
export CC="${stagingDir}/bin/${targetArch}-gcc" | |
export LD="${stagingDir}/bin/${targetArch}-ld" | |
export NM="${stagingDir}/bin/${targetArch}-nm" | |
export OBJCOPY="${stagingDir}/bin/${targetArch}-objcopy" | |
export OBJDUMP="${stagingDir}/bin/${targetArch}-objdump" | |
export RANLIB="${stagingDir}/bin/${targetArch}-ranlib" | |
export READELF="${stagingDir}/bin/${targetArch}-readelf" | |
export STRIP="${stagingDir}/bin/${targetArch}-strip" | |
make_dependency "$GMP_RELEASE_LATEST" gmp "$hostArch" "$targetArch" "$stagingDir" "$workingDir" | |
make_dependency "$MPFR_RELEASE_LATEST" mpfr "$hostArch" "$targetArch" "$stagingDir" "$workingDir" | |
make_dependency "$MPC_RELEASE_LATEST" mpc "$hostArch" "$targetArch" "$stagingDir" "$workingDir" | |
make_dependency "$ISL_RELEASE_LATEST" isl "$hostArch" "$targetArch" "$stagingDir" "$workingDir" | |
#make_dependency "$CLOOG_RELEASE_LATEST" cloog "$hostArch" "$targetArch" "$stagingDir" "$workingDir" | |
make_kernel_headers "$kernelVer" "$workingDir" "$targetDir" "$targetArch" | |
export PATH="${stagingDir}/bin:$oldPath:${stagingDir}/${targetArch}/bin" | |
BUILD_DIR_SUFFIX="target" | |
make_dependency "$GMP_RELEASE_LATEST" gmp "$hostArch" "$targetArch" "$targetDir" "$workingDir" | |
make_dependency "$MPFR_RELEASE_LATEST" mpfr "$hostArch" "$targetArch" "$targetDir" "$workingDir" | |
make_dependency "$MPC_RELEASE_LATEST" mpc "$hostArch" "$targetArch" "$targetDir" "$workingDir" | |
make_dependency "$ISL_RELEASE_LATEST" isl "$hostArch" "$targetArch" "$targetDir" "$workingDir" | |
#make_dependency "$CLOOG_RELEASE_LATEST" cloog "$hostArch" "$targetArch" "$targetDir" "$workingDir" | |
configure_binutils "$binutilsVer" "$releaseVer" "$workingDir" "$targetDir" "$hostArch" "$targetArch" 2 | |
make_binutils "$binutilsVer" "$releaseVer" "$workingDir" | |
configure_gcc_cross "$releaseVer" "$newlibVer" "$workingDir" "$targetDir" "$targetArch" "$targetArch" 1 1 | |
make_gcc_cross "$releaseVer" "$workingDir" "$targetDir" "$targetArch" 1 | |
if [[ -n "$glibcVer" ]]; then | |
make_glibc "$releaseVer" "$kernelVer" "$glibcVer" "$targetArch" "$targetArch" "$targetDir" "$workingDir" 1 | |
else | |
make_newlib "$releaseVer" "$newlibVer" "$targetArch" "$targetArch" "$targetDir" "$workingDir" 1 | |
fi | |
configure_gcc_cross "$releaseVer" "$newlibVer" "$workingDir" "$targetDir" "$targetArch" "$targetArch" 2 1 | |
make_gcc_cross "$releaseVer" "$workingDir" "$targetDir" "$targetArch" 2 | |
if [[ -n "$glibcVer" ]]; then | |
make_glibc "$releaseVer" "$kernelVer" "$glibcVer" "$targetArch" "$targetArch" "$targetDir" "$workingDir" 2 | |
fi | |
configure_gcc_cross "$releaseVer" "$newlibVer" "$workingDir" "$targetDir" "$targetArch" "$targetArch" 3 1 | |
make_gcc_cross "$releaseVer" "$workingDir" "$targetDir" "$targetArch" 3 | |
} | |
main $@ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment