Skip to content

Instantly share code, notes, and snippets.

@guilledk
Created December 9, 2018 22:01
Show Gist options
  • Save guilledk/4cdf88f2e4039cac7673c5b3328d26ff to your computer and use it in GitHub Desktop.
Save guilledk/4cdf88f2e4039cac7673c5b3328d26ff to your computer and use it in GitHub Desktop.
Attempt at making an automated gcc cross compiler isntaller, needs work...
#!/usr/bin/env sh
# Usage:
# sh cross-gcc-install.sh [arguments]
# Use this script to download, build and install a gcc cross compiler in ubuntu. Requires root permisions.\n
# Arguments:
#
# [-t|--target] - Set target architecture. Default: "i686-elf"
# [-df|--dependency-file] - Set explicit dependency file. Will try to install with apt-get. Default: "gcc-build-requirements"
# [-lf|--log-file] - Set log file. Default: ".gcc-install-log"
# [-nc|--no-color] - Disable ANSI color printing.
# [-h|--help] - Show this help text and exit.
# Exit codes:
#
# 0 - Success.
# 1 - Invalid argument.
# 2 - User aborted.
# 3 - apt-get failed.
# 4 - wget error.
#This script requires root permisions, also uses ANSI escape codes to print
#colors to the terminal, disable this feature passing "--no-color".
#color_printf: Print text with color using ANSI escape codes.
#args:
# 1: string to print.
# 2: color, must be an ANSI escape secuence.
color_printf() {
printf "$2"
printf "$1"
printf "$ANSI_RESET"
}
#log: Appends a string with timestamp and log type to the log file.
#args:
# 1: log tag, valid types are: "INFO", "WARNING" and "ERROR".
# 2: string to log.
log() {
printf "[$(date "+%d %m %Y %H:%M:%S")]" >> $LOG_FILE
case "$1" in
"INFO"|"info"|"i" )
printf "[ INFO ]: " >> $LOG_FILE
;;
"WARNING"|"warning"|"w" )
printf "[WARNING]: " >> $LOG_FILE
;;
"ERROR"|"error"|"e" )
printf "[ ERROR ]: " >> $LOG_FILE
;;
esac
echo "$2" >> $LOG_FILE
}
#pipe_log: Appends pipe input string with timestamp and log type to the log file.
#args:
# 1: log tag, valid types are: "INFO", "WARNING" and "ERROR".
pipe_log() {
while read pinput; do
printf "[$(date "+%d %m %Y %H:%M:%S")]" >> $LOG_FILE
case "$1" in
"INFO"|"info"|"i" )
printf "[ INFO ]: " >> $LOG_FILE
;;
"WARNING"|"warning"|"w" )
printf "[WARNING]: " >> $LOG_FILE
;;
"ERROR"|"error"|"e" )
printf "[ ERROR ]: " >> $LOG_FILE
;;
esac
echo "$pinput" >> $LOG_FILE
done
}
ANSI_RESET="\e[0m"
ANSI_RED="\e[31m"
ANSI_GREEN="\e[32m"
ANSI_YELLOW="\e[33m"
DEPENDENCIES_FILE="gcc-build-requirements"
LOG_FILE=".gcc-install-log"
COMPILER_TARGET="i686-elf"
PIPE_STDOUT=".log_stdout"
PIPE_STDWRN=".log_stdwrn"
PIPE_STDERR=".log_stderr"
HELP_TEXT="
Usage:\n
\"sh cross-gcc-install.sh [arguments]\"\n
Use this script to download, build and install a gcc cross compiler in debian based systems. Requires root permisions.\n
Arguments:
[-t|--target] - Set target architecture. Default: "i686-elf"
[-df|--dependency-file] - Set Dependency file Will try to install with apt-get. Default: "gcc-build-requirements"
[-lf|--log-file] - Set log file. Default: .gcc-install-log
[-nc|--no-color] - Disable ANSI color printing.
[-h|--help] - Show this help text and exit.\n
Exit codes:
0 - Success.
1 - Invalid argument.
3 - apt-get failed.
4 - wget error."
help_flag="no"
while [ $# -gt 0 ]; do
arg="$1"
case "$arg" in
"-nc"|"--no-color" )
ANSI_RESET=""
ANSI_RED=""
ANSI_GREEN=""
ANSI_YELLOW=""
;;
"-h"|"--help" )
help_flag="0"
;;
"-df"|"--dependency-file" )
shift
DEPENDENCIES_FILE="$1"
;;
"-lf"|"--log-file" )
shift
LOG_FILE="$1"
;;
-t|--target )
shift
COMPILER_TARGET="$1"
;;
* )
printf "Invalid argument!: \"$arg\"."
help_flag="1"
;;
esac
shift
done
if [ "$help_flag" != "no" ]; then
color_printf "$HELP_TEXT\n" $ANSI_YELLOW
exit $help_flag
fi
printf "Log file location: "
color_printf "$LOG_FILE\n" $ANSI_YELLOW
BINUTILS_SOURCE_URL="https://ftp.gnu.org/gnu/binutils/binutils-2.30.tar.gz"
GCC_SOURCE_URL="https://ftp.gnu.org/gnu/gcc/gcc-7.3.0/gcc-7.3.0.tar.gz"
echo "$ANSI_GREEN BINUTILS $ANSI_RESET compressed source from: \n\t$ANSI_YELLOW$BINUTILS_SOURCE_URL$ANSI_RESET"
echo "$ANSI_GREEN GCC $ANSI_RESET compressed source from: \n\t$ANSI_YELLOW$GCC_SOURCE_URL$ANSI_RESET"
INSTALL_DIRECTORY="/usr/local/cross"
while true; do
printf "Directory for gcc cross compiler instalation (default is "
color_printf "\"/usr/local/cross/\"" $ANSI_YELLOW
read -p "):" USER_INPUT
case $USER_INPUT in
"" )
break;;
* )
echo "Install location:"
color_printf "\t$USER_INPUT\n" $ANSI_YELLOW
while true; do
printf "Are you sure? ("
color_printf "yY" $ANSI_GREEN
printf "/"
color_printf "nN" $ANSI_RED
read -p "): " OPTION
exit="false"
echo "\"$OPTION\""
case $OPTION in
[yY]* | "" )
INSTALL_DIRECTORY="$USER_INPUT"
exit="true"
break;;
[nN]* )
break;;
esac
done
if [ "$exit" = "true" ]; then
break
fi;;
esac
done
#Create pipes to redirect programs output.
mkfifo "$PIPE_STDOUT"
mkfifo "$PIPE_STDWRN"
mkfifo "$PIPE_STDERR"
tail -n +1 -f "$PIPE_STDOUT" | pipe_log "i" &
tail -n +1 -f "$PIPE_STDWRN" | pipe_log "w" &
tail -n +1 -f "$PIPE_STDERR" | pipe_log "e" &
mkdir -p $INSTALL_DIRECTORY 2>"$PIPE_STDWRN"
printf "Install directory set to: "
color_printf "$INSTALL_DIRECTORY\n" $ANSI_YELLOW
log "i" "Created install directory at $INSTALL_DIRECTORY"
printf "To build "
color_printf "gcc" $ANSI_GREEN
printf " and "
color_printf "binutils" $ANSI_GREEN
printf " we need to get the following "
color_printf "dependencies" $ANSI_YELLOW
printf ": \n"
apt_dependency_str=""
while read -r dependency; do
apt_dependency_str="$apt_dependency_str $dependency"
echo "\t$dependency"
done < "$DEPENDENCIES_FILE"
while true; do
printf "Do you wish to continue? ("
color_printf "yY" $ANSI_GREEN
printf "/"
color_printf "nN" $ANSI_RED
read -p "): " OPTION
case $OPTION in
[yY]* | "" )
INSTALL_DIRECTORY="$USER_INPUT"
break;;
[nN]* )
color_printf "User aborted.\n" $ANSI_RED
log "i" "User aborted script at dependency instalation phase. Quitting..."
exit 2;;
esac
done
echo "Installing dependencies with apt-get..."
apt-get install $apt_dependency_str 1>"$PIPE_STDOUT" 2>"$PIPE_STDERR"
if [ "$?" = "100" ]; then
color_printf "Error installing dependencies" $ANSI_RED
echo ", check log file for more information."
log "e" "apt-get error!. Quitting..."
exit 3
fi
color_printf "Success" $ANSI_GREEN
echo " installing dependencies."
log "i" "Successfully installed dependencies."
export PREFIX="$INSTALL_DIRECTORY"
export TARGET="$COMPILER_TARGET"
export PATH="$PREFIX/bin:$PATH"
mkdir src 2>"$PIPE_STDWRN"
echo "Downloading sources..."
printf " Downloading "
color_printf "binutils" $ANSI_YELLOW
echo " please wait..."
log "i" "Started downloading binutils source from $BINUTILS_SOURCE_URL"
#wget -O src/binutils-source.tar.gz $BINUTILS_SOURCE_URL -q --show-progress
if [ "$?" != "0" ]; then
color_printf "Error getting sources" $ANSI_RED
echo ", check log file for more information."
log "e" "wget error!. Quitting..."
exit 4
fi
color_printf "Finished downloading binutils.\n" $ANSI_GREEN
log "i" "Finished downloading binutils source from $BINUTILS_SOURCE_URL"
printf " Downloading "
color_printf "gcc" $ANSI_YELLOW
echo " please wait..."
log "i" "Started downloading gcc source from $GCC_SOURCE_URL"
#wget -O src/gcc-source.tar.gz $GCC_SOURCE_URL -q --show-progress
if [ "$?" != "0" ]; then
color_printf "Error getting sources" $ANSI_RED
echo ", check log file for more information."
log "e" "wget error!. Quitting..."
exit 4
fi
color_printf "Finished downloading gcc.\n" $ANSI_GREEN
log "i" "Finished downloading gcc source from $GCC_SOURCE_URL"
echo "Extracting source files..."
log "i" "Extracting binutils..."
tar -xf src/binutils-source.tar.gz -C src/ 1>"$PIPE_STDOUT" 2>"$PIPE_STDERR"
log "i" "Done."
log "i" "Extracting gcc..."
tar -xf src/gcc-source.tar.gz -C src/ 1>"$PIPE_STDOUT" 2>"$PIPE_STDERR"
log "i" "Done."
echo "Finished extracting sources."
echo "Deleting compressed source files..."
rm src/binutils-source.tar.gz
rm src/gcc-source.tar.gz
echo "Compressed sources deleted."
log "i" "Deleted compressed sources."
binutils_src_folder="$(ls src | grep binutils)"
gcc_src_folder="$(ls src | grep gcc)"
log "i" "binutils source folder: $binutils_src_folder"
log "i" "gcc source folder: $gcc_src_folder"
log "i" "Building binutils..."
color_printf "Building binutils..." $ANSI_YELLOW
mkdir -p build/binutils 1>"$PIPE_STDOUT" 2>"$PIPE_STDERR"
cd build/binutils
printf "\nBINUTILS source directory is: \n\t"
color_printf "$binutils_src_folder" $ANSI_YELLOW
printf "\nRunning \"configure\"..."
../../src/$binutils_src_folder/configure --target=$TARGET --prefix="$PREFIX" --with-sysroot --disable-nls --disable-werror 1>"$PIPE_STDOUT" 2>"$PIPE_STDERR"
echo "Done."
printf "Running \"make\"..."
make 1>"$PIPE_STDOUT" 2>"$PIPE_STDERR"
echo "Done."
printf "Running \"make install\"..."
make install 1>"$PIPE_STDOUT" 2>"$PIPE_STDERR"
echo "Done."
color_printf "Finished building binutils!\n" $ANSI_GREEN
log "i" "Finished building binutils."
log "i" "Building gcc..."
color_printf "Building gcc..." $ANSI_YELLOW
mkdir -p build/gcc 1>"$PIPE_STDOUT" 2>"$PIPE_STDERR"
cd build/gcc
printf "\nGCC source directory is: \n\t"
color_printf "$gcc_src_folder" $ANSI_YELLOW
printf "\nRunning \"configure\"..."
../../src/$gcc_src_folder/configure --target=$TARGET --prefix="$PREFIX" --disable-nls --enable-languages=c,c++ --without-headers 1>"$PIPE_STDOUT" 2>"$PIPE_STDERR"
echo "Done."
printf "Running \"make all-gcc\"..."
make all-gcc 1>"$PIPE_STDOUT" 2>"$PIPE_STDERR"
echo "Done."
printf "Running \"make all-target-libgcc\"..."
make all-target-libgcc 1>"$PIPE_STDOUT" 2>"$PIPE_STDERR"
echo "Done."
printf "Running \"make install-gcc\"..."
make install-gcc 1>"$PIPE_STDOUT" 2>"$PIPE_STDERR"
echo "Done."
printf "Running \"make install-target-libgcc\"..."
make install-target-libgcc 1>"$PIPE_STDOUT" 2>"$PIPE_STDERR"
echo "Done."
color_printf "Finished building gcc!\n" $ANSI_GREEN
log "i" "Finished building gcc."
#Delete pipes.
rm $PIPE_STDOUT $PIPE_STDWRN $PIPE_STDERR
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment