Created
December 9, 2018 22:01
-
-
Save guilledk/4cdf88f2e4039cac7673c5b3328d26ff to your computer and use it in GitHub Desktop.
Attempt at making an automated gcc cross compiler isntaller, needs work...
This file contains hidden or 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 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