Dyad/rex.project/x86_64/components/gcc.bash

551 lines
13 KiB
Bash
Executable File

#!/bin/bash
# desc:
# stages, builds, installs
# make variables persist in subprocesses for logging function
set -a
# ----------------------------------------------------------------------
# Configuration:
# ----------------------------------------------------------------------
# the name of this application
APPNAME="gcc"
# the version of this application
VERSION="12.2.0"
MPFR_V="4.2.0"
GMP_V="6.2.1"
MPC_V="1.3.1"
# ----------------------------------------------------------------------
# Variables and functions sourced from Environment:
# ----------------------------------------------------------------------
# assert_zero()
# Checks if $1 is 0. If non-0 value, halts the execution of the script.
#
# LOGS_ROOT
# The parent directory where logs from this project will go.
#
# TEMP_STAGE_DIR
# The parent directory of where source archives are extracted to.
# register mode selections
ARGUMENT_LIST=(
"stage"
"build_gcc_pass1"
"install_gcc_pass1"
"build_gcc_pass2"
"install_gcc_pass2"
"build_libstdcxx_pass1"
"install_libstdcxx_pass1"
"build_libstdcxx_pass2"
"install_libstdcxx_pass2"
"gcc_pass1"
"gcc_pass2"
"libstdcxx_pass1"
"libstdcxx_pass2"
"help"
)
mode_help() {
echo "${APPNAME} [ --stage ] [ --build_gcc_pass1 ] [ --install_gcc_pass1 ] [ --build_gcc_pass2 ] [ --install_gcc_pass2 ] [ --build_libstdcxx_pass1 ] [ --install_libstdcxx_pass1 ] [ --build_libstdcxx_pass2 ] [ --install_libstdcxx_pass2 ] [ --gcc_pass1 ] [ --gcc_pass2 ] [ --libstdcxx_pass1 ] [ --libstdcxx_pass2 ] [ --help ]"
exit 0
}
# modes to associate with switches
# assumes you want nothing done unless you ask for it.
MODE_STAGE=false
MODE_BUILD_GCC_PASS1=false
MODE_INSTALL_GCC_PASS1=false
MODE_BUILD_GCC_PASS2=false
MODE_INSTALL_GCC_PASS2=false
MODE_BUILD_LIBSTDCXX_PASS1=false
MODE_INSTALL_LIBSTDCXX_PASS1=false
MODE_BUILD_LIBSTDCXX_PASS2=false
MODE_INSTALL_LIBSTDCXX_PASS2=false
MODE_LIBSTDCXX_PASS1=false
MODE_LIBSTDCXX_PASS2=false
MODE_GCC_PASS1=false
MODE_GCC_PASS2=false
MODE_HELP=false
# the file to log to
LOGFILE="${APPNAME}.log"
# ISO 8601 variation
TIMESTAMP="$(date +%Y-%m-%d_%H:%M:%S)"
# the path where logs are written to
# note: LOGS_ROOT is sourced from environment
LOG_DIR="${LOGS_ROOT}/${APPNAME}-${TIMESTAMP}"
# the path where the source will be located when complete
# note: TEMP_STAGE_DIR is sourced from environment
T_SOURCE_DIR="${TEMP_STAGE_DIR}/${APPNAME}"
# read defined arguments
opts=$(getopt \
--longoptions "$(printf "%s," "${ARGUMENT_LIST[@]}")" \
--name "$APPNAME" \
--options "" \
-- "$@"
)
# process supplied arguments into flags that enable execution modes
eval set --$opts
while [[ $# -gt 0 ]]; do
case "$1" in
--stage)
MODE_STAGE=true
shift 1
;;
--build_gcc_pass1)
MODE_BUILD_GCC_PASS1=true
shift 1
;;
--install_gcc_pass1)
MODE_INSTALL_GCC_PASS1=true
shift 1
;;
--build_gcc_pass2)
MODE_BUILD_GCC_PASS2=true
shift 1
;;
--install_gcc_pass2)
MODE_INSTALL_GCC_PASS2=true
shift 1
;;
--build_libstdcxx_pass1)
MODE_BUILD_LIBSTDCXX_PASS1=true
shift 1
;;
--install_libstdcxx_pass1)
MODE_INSTALL_LIBSTDCXX_PASS1=true
shift 1
;;
--build_libstdcxx_pass2)
MODE_BUILD_LIBSTDCXX_PASS2=true
shift 1
;;
--install_libstdcxx_pass2)
MODE_INSTALL_LIBSTDCXX_PASS2=true
shift 1
;;
--gcc_pass1)
MODE_GCC_PASS1=true
shift 1
;;
--gcc_pass2)
MODE_GCC_PASS2=true
shift 1
;;
--libstdcxx_pass1)
MODE_LIBSTDCXX_PASS1=true
shift 1
;;
--libstdcxx_pass2)
MODE_LIBSTDCXX_PASS2=true
shift 1
;;
--help)
MODE_HELP=true
shift 1
;;
*)
break
;;
esac
done
# print to stdout, print to log
logprint() {
mkdir -p "${LOG_DIR}"
echo "[$(date +%Y-%m-%d_%H:%M:%S)] [${APPNAME}] $1" \
| tee -a "${LOG_DIR}/${LOGFILE}"
}
# Tell the user we're alive...
logprint "Initializing the ${APPNAME} utility..."
# when the stage mode is enabled, this will execute
mode_stage() {
logprint "Starting stage of ${APPNAME}..."
logprint "Removing any pre-existing staging for ${APPNAME}."
rm -Rf "${T_SOURCE_DIR}"*
logprint "Extracting ${APPNAME}-${VERSION} source archive to ${TEMP_STAGE_DIR}"
tar xf "${SOURCES_DIR}/${APPNAME}-${VERSION}.tar."* -C "${TEMP_STAGE_DIR}"
assert_zero $?
# conditionally rename if it needs it
stat "${T_SOURCE_DIR}-"* && mv "${T_SOURCE_DIR}-"* "${T_SOURCE_DIR}"
pushd ${T_SOURCE_DIR}
assert_zero $?
# MPFR
logprint "Extracting MPFR"
tar xf "${SOURCES_DIR}/mpfr-${MPFR_V}.tar.xz" -C "${T_SOURCE_DIR}"
assert_zero $?
logprint "Staging MPFR"
mv "${T_SOURCE_DIR}/mpfr-"* "${T_SOURCE_DIR}/mpfr"
assert_zero $?
# GMP
logprint "Extracting GMP"
tar xf "${SOURCES_DIR}/gmp-${GMP_V}.tar.xz" -C "${T_SOURCE_DIR}"
assert_zero $?
logprint "Staging GMP"
mv "${T_SOURCE_DIR}/gmp-"* "${T_SOURCE_DIR}/gmp"
assert_zero $?
# MPC
logprint "Extracting MPC"
tar xf "${SOURCES_DIR}/mpc-${MPC_V}.tar.gz" -C "${T_SOURCE_DIR}"
assert_zero $?
logprint "Staging MPC"
mv "${T_SOURCE_DIR}/mpc-"* "${T_SOURCE_DIR}/mpc"
assert_zero $?
logprint "Staging operation complete."
}
mode_build_libstdcxx_pass1() {
logprint "Starting build of LIBSTDC++/pass1..."
logprint "Entering build dir."
pushd "${T_SOURCE_DIR}"
assert_zero $?
mkdir -p build
pushd build
assert_zero $?
logprint "Configuring libstdc++..."
# Note: This currently depends on crosstools being in the top level dir of the T_SYSROOT
# use a substring in the future
../libstdc++-v3/configure \
--host=${T_TRIPLET} \
--build=$(../config.guess) \
--prefix=/usr \
--disable-multilib \
--disable-nls \
--disable-libstdcxx-pch \
--with-gxx-include-dir=/$(basename ${CROSSTOOLS_DIR})/${T_TRIPLET}/include/c++/10.2.0
assert_zero $?
logprint "Compiling..."
make
assert_zero $?
logprint "Build operation complete."
}
mode_build_libstdcxx_pass2() {
# this is meant to be kicked off from the chroot context. do not expect
# this to work at all with a direct execution context from outside of the chroot.
logprint "Starting build of LIBSTDC++/pass2..."
logprint "Entering build dir."
pushd "${T_SOURCE_DIR}"
assert_zero $?
ln -s gthr-posix.h libgcc/gthr-default.h
assert_zero $?
mkdir -p build
pushd build
assert_zero $?
logprint "Configuring libstdc++..."
# Note: This currently depends on crosstools being in the top level dir of the T_SYSROOT
# use a substring in the future
../libstdc++-v3/configure \
CXXFLAGS="-g -O2 -D_GNU_SOURCE" \
--prefix=/usr \
--disable-multilib \
--disable-nls \
--host=${T_TRIPLET} \
--disable-libstdcxx-pch
assert_zero $?
logprint "Compiling..."
make
assert_zero $?
logprint "Build operation complete."
}
mode_install_libstdcxx_pass1() {
logprint "Starting install of LIBSTDC++/pass1..."
pushd "${T_SOURCE_DIR}/build"
assert_zero $?
make DESTDIR=${T_SYSROOT} install
assert_zero $?
logprint "Install of libstdcxx complete."
}
mode_install_libstdcxx_pass2() {
logprint "Starting install of LIBSTDC++/pass1..."
pushd "${T_SOURCE_DIR}/build"
assert_zero $?
make install
assert_zero $?
logprint "Install of libstdcxx complete."
}
# when the build_pass1 mode is enabled, this will execute
mode_build_gcc_pass1() {
logprint "Starting build of ${APPNAME}/pass1..."
logprint "Entering build dir."
pushd "${T_SOURCE_DIR}"
assert_zero $?
# patches
logprint "Applying patches..."
patch -p0 < "${PATCHES_DIR}/gcc_libarchpath_fhs.patch"
assert_zero $?
mkdir -p build
pushd build
assert_zero $?
logprint "Configuring ${APPNAME}..."
../configure \
--target=${T_TRIPLET} \
--prefix=${CROSSTOOLS_DIR} \
--with-glibc-version=2.37 \
--with-sysroot=${T_SYSROOT} \
--with-newlib \
--without-headers \
--enable-default-pie \
--enable-default-ssp \
--disable-nls \
--disable-shared \
--disable-multilib \
--disable-threads \
--disable-libatomic \
--disable-libgomp \
--disable-libquadmath \
--disable-libssp \
--disable-libvtv \
--disable-libstdcxx \
--enable-languages=c,c++
assert_zero $?
logprint "Compiling..."
make
assert_zero $?
logprint "Build operation complete."
}
mode_build_gcc_pass2() {
logprint "Starting build of ${APPNAME}/pass2..."
logprint "Entering build dir."
pushd "${T_SOURCE_DIR}"
assert_zero $?
# patches
logprint "Applying patches..."
patch -p0 < "${PATCHES_DIR}/gcc_libarchpath_fhs.patch"
assert_zero $?
logprint "Entering build subdirectory"
mkdir -p build
pushd build
assert_zero $?
logprint "Creating posix thread support compatibility symlink..."
mkdir -pv ${T_TRIPLET}/libgcc
assert_zero $?
ln -s ../../../libgcc/gthr-posix.h ${T_TRIPLET}/libgcc/gthr-default.h
assert_zero $?
logprint "Configuring ${APPNAME}..."
../configure \
--build=$(../config.guess) \
--host=${T_TRIPLET} \
--prefix=/usr \
CC_FOR_TARGET=${T_TRIPLET}-gcc \
--with-build-sysroot=${T_SYSROOT} \
--enable-initfini-array \
--disable-nls \
--disable-multilib \
--disable-decimal-float \
--disable-libatomic \
--disable-libgomp \
--disable-libquadmath \
--disable-libssp \
--disable-libvtv \
--disable-libstdcxx \
--enable-languages=c,c++
assert_zero $?
logprint "Compiling..."
make
assert_zero $?
logprint "Build operation complete."
}
mode_install_gcc_pass2() {
logprint "Starting install of ${APPNAME}/pass2..."
pushd "${T_SOURCE_DIR}/build"
assert_zero $?
make -j1 DESTDIR=${T_SYSROOT} install
assert_zero $?
logprint "Clean up items..."
logprint "CC/GCC utility symlink"
ln -sv gcc ${T_SYSROOT}/usr/bin/cc
assert_zero $?
logprint "Install operation complete."
}
mode_install_gcc_pass1() {
logprint "Starting install of ${APPNAME}/pass1..."
pushd "${T_SOURCE_DIR}/build"
assert_zero $?
make install
assert_zero $?
logprint "Install operation complete."
logprint "Wrapping up headers..."
popd
pushd "${T_SOURCE_DIR}"
assert_zero $?
cat gcc/limitx.h gcc/glimits.h gcc/limity.h > `dirname $(${T_TRIPLET}-gcc -print-libgcc-file-name)`/install-tools/include/limits.h
assert_zero $?
}
# MODE_GCC_PASS1 is a meta toggle for all pass1 modes. Modes will always
# run in the correct order.
if [ "$MODE_GCC_PASS1" = "true" ]; then
echo "PASS1 selected"
logprint "PASS1 selected."
MODE_STAGE=true
MODE_BUILD_GCC_PASS1=true
MODE_INSTALL_GCC_PASS1=true
fi
if [ "$MODE_GCC_PASS2" = "true" ]; then
logprint "PASS2 selected."
MODE_STAGE=true
MODE_BUILD_GCC_PASS2=true
MODE_INSTALL_GCC_PASS2=true
fi
if [ "$MODE_LIBSTDCXX_PASS1" = "true" ]; then
logprint "LIBSTDCXX PASS1 selected."
MODE_BUILD_LIBSTDCXX_PASS1=true
MODE_INSTALL_LIBSTDCXX_PASS1=true
fi
if [ "$MODE_LIBSTDCXX_PASS2" = "true" ]; then
logprint "LIBSTDCXX PASS2 selected."
MODE_STAGE=true
MODE_BUILD_LIBSTDCXX_PASS2=true
MODE_INSTALL_LIBSTDCXX_PASS2=true
fi
# if no options were selected, then show help and exit
if \
[ "$MODE_HELP" != "true" ] && \
[ "$MODE_STAGE" != "true" ] && \
[ "$MODE_BUILD_GCC_PASS1" != "true" ] && \
[ "$MODE_INSTALL_GCC_PASS1" != "true" ] && \
[ "$MODE_BUILD_GCC_PASS2" != "true" ] && \
[ "$MODE_INSTALL_PASS2" != "true" ] && \
[ "$MODE_BUILD_LIBSTDCXX_PASS1" != "true" ] && \
[ "$MODE_INSTALL_LIBSTDCXX_PASS1" != "true" ] && \
[ "$MODE_BUILD_LIBSTDCXX_PASS2" != "true" ] && \
[ "$MODE_INSTALL_LIBSTDCXX_PASS2" != "true" ]
then
logprint "No option selected during execution."
mode_help
fi
# if help was supplied at all, show help and exit
if [ "$MODE_HELP" = "true" ]; then
logprint "Help option selected. Printing options and exiting."
mode_help
fi
if [ "$MODE_STAGE" = "true" ]; then
logprint "Staging option selected."
mode_stage
assert_zero $?
fi
if [ "$MODE_BUILD_GCC_PASS1" = "true" ]; then
logprint "Build of PASS1 selected."
mode_build_gcc_pass1
assert_zero $?
fi
if [ "$MODE_INSTALL_GCC_PASS1" = "true" ]; then
logprint "Install of PASS1 selected."
mode_install_gcc_pass1
assert_zero $?
fi
if [ "$MODE_BUILD_GCC_PASS2" = "true" ]; then
logprint "Build of PASS2 selected."
mode_build_gcc_pass2
assert_zero $?
fi
if [ "$MODE_INSTALL_GCC_PASS2" = "true" ]; then
logprint "Install of PASS2 selected."
mode_install_gcc_pass2
assert_zero $?
fi
if [ "$MODE_BUILD_LIBSTDCXX_PASS1" = "true" ]; then
logprint "Build of LIBSTDC++ selected."
mode_build_libstdcxx_pass1
assert_zero $?
fi
if [ "$MODE_INSTALL_LIBSTDCXX_PASS1" = "true" ]; then
logprint "INSTALL of LIBSTDC++ selected."
mode_install_libstdcxx_pass1
assert_zero $?
fi
if [ "$MODE_BUILD_LIBSTDCXX_PASS2" = "true" ]; then
logprint "Build of LIBSTDC++ selected."
mode_build_libstdcxx_pass2
assert_zero $?
fi
if [ "$MODE_INSTALL_LIBSTDCXX_PASS2" = "true" ]; then
logprint "INSTALL of LIBSTDC++ selected."
mode_install_libstdcxx_pass2
assert_zero $?
fi
logprint "Execution of ${APPNAME} completed."