summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rwxr-xr-xcompile.sh493
1 files changed, 363 insertions, 130 deletions
diff --git a/compile.sh b/compile.sh
index 166edea54..0f26f8607 100755
--- a/compile.sh
+++ b/compile.sh
@@ -3,39 +3,183 @@
{ # put the whole thing in a block so as not to behave weirdly if interrupted
set -e
-#TODO command line parameter handling for non-interactive mode.
+# Global variables:
+# CHOICE_BUILDTYPE - Either "Normal" or "Debug".
+# CHOICE_THREADS - A numerical value, the amount of threads to be used for the make command.
+# CHOICE_BRANCH - The branch to use. Currently locked on "master".
+# STATE_INTERACTIVE - 1 If we're running interactively. 0 otherwise.
+# STATE_NEW - Whether this is the first run. If 1, then no GIT repo exists yet. 0 otherwise.
-# Do we already have a repo?
-if [ -d .git ] && [ -f easyinstall.sh ] && [ -f src/BlockArea.cpp ]; then # A good enough indicator that we're in the Cuberite git repo.
- cd ../
- echo "Cuberite repository detected. This should make the process faster, especially if you compiled before."
-fi
+# Constants:
+DEFAULT_BUILDTYPE="Release" # Other options: "Debug"
+DEFAULT_BRANCH="master" # Other options: None currently
+DEFAULT_THREADS=2
+
+# Constants not modifiable through command line:
+UPSTREAM_REPO="origin"
+UPSTREAM_LINK="https://github.com/cuberite/cuberite.git"
+DRY_RUN="no"
+
+#=================== Error functions ===================
-# Error functions.
-error ()
+
+errorCompile ()
{
echo
- echo "-----------------"
- echo "Script aborted, reason:"
+ echoInt "-----------------"
+ echo "Compilation failed. Failed command:"
echo "$@"
exit 1
}
-missingDepsExit ()
+errorGit ()
{
- if [ "$1" != "" ]; then
- echo "You can install the missing depndencies via:"
- echo "$1"
- fi
- echo
- echo "Please install the dependencies, then come back."
echo
+ echoInt "-----------------"
+ echo "Code fetch failed. (Check your network connection). Failed command:"
+ echo "$@"
exit 2
}
+errorDependencies ()
+{
+ # The error messages are complex and OS-dependant, and are printed in the dependencies section before this is called.
+ exit 3
+}
+
+errorArguments ()
+{
+ echo "Usage: ./compile.sh [options]"
+ echo "Compiles Cuberite. Updates the GIT repository if needed, and downloads it if it does not exist."
+ echo "Runs interactively, unless one or more options are specified."
+ echo
+ echo "options:"
+ echo " -m The compilation mode. Either \"Release\" or \"Debug\". Defaults to \"$DEFAULT_BUILDTYPE\""
+ echo ' -t The number of threads to use for compiling'
+ echo ' If unspecified, a "smart guess" is attempted (Currently simply picks 2)'
+ echo ' -b The branch to compile. (Currently unused and pinned to MASTER)'
+ echo ' -n Prevent interactive mode'
+ echo ' -d Dry run. Print the chosen settings and exit'
+ echo
+ echo "Usage examples:"
+ echo " ./compile.sh"
+ echo " ./compile.sh -m Debug"
+ echo " ./compile.sh -m Release -t 2"
+ echo
+ echo "Return codes: (non 0 returns are accompanied by useful stderr info)"
+ echo "0 - Success - Success! Code was updated and compiled"
+ echo "1 - Compilation failed - cmake, make, or source code issue"
+ echo "2 - Code fetch failed - Network issue or, far more rarely, a git issue"
+ echo "3 - Dependencies missing - Some compilation tools are missing"
+ echo "4 - Bad arguments - Bad commandline arguments were passed"
+ echo "5 - Bad user input - Invalid user input in interactive mode"
+ echo "6 - other - An error not listed above"
+ exit 4
+}
+
+errorInput ()
+{
+ echo
+ echoInt "-----------------"
+ echo "Unrecognized user input"
+ echo "$@"
+ exit 5
+}
+
+errorOther ()
+{
+ echo
+ echoInt "-----------------"
+ echo "$@"
+ exit 6
+}
+
+
+#=================== Echo functions ===================
+
+
+echoInt () # echo only if interactive mode.
+{
+ if [ $STATE_INTERACTIVE -eq 1 ]; then
+ echo "$1"
+ fi
+}
+
+echoErr () # Echo to stderr.
+{
+ echo "$1" 1>&2
+}
+
+
+#=================== Commandline Parsing ===================
+
+
+STATE_INTERACTIVE=1 # Interactive, unless one or more command line options are passed.
+while getopts ":m:t:b:" name; do
+ value=$OPTARG
+ STATE_INTERACTIVE=0
+ case "$name" in
+ m)
+ if [ ! -z "$CHOICE_BUILDTYPE" ]; then errorArguments; fi # Argument duplication.
+ if [ "$value" = "Debug" ] || [ "$value" = "Release" ]; then
+ CHOICE_BUILDTYPE="$value"
+ else
+ errorArguments
+ fi
+ ;;
+ t)
+ if [ ! -z "$CHOICE_THREADS" ]; then errorArguments; fi # Argument duplication.
+ if [ "$value" -gt 0 ] 2>/dev/null; then # If a positive integer.
+ CHOICE_THREADS="$value"
+ else
+ errorArguments
+ fi
+ ;;
+ b)
+ if [ ! -z "$CHOICE_BRANCH" ]; then errorArguments; fi # Argument duplication.
+ CHOICE_BRANCH=1 # Only used for dupe checking, overridden below.
+ echoErr "Warning: The -b option is currently unused, it was ignored"
+ ;;
+ n)
+ if [ "$dummy" = "1" ]; then errorArguments; fi # Argument duplication.
+ dummy=1
+ ;;
+ *)
+ errorArguments
+ ;;
+ esac
+done
+
+
+#=================== Dependency checks and greeting ===================
+
+
+# Do we already have a repo?
+checkCuberiteDir ()
+{
+ [ -d .git ] && [ -f easyinstall.sh ] && [ -f src/BlockArea.cpp ] # A good enough indicator that we're in the Cuberite git repo.
+}
+
+STATE_NEW=1
+if checkCuberiteDir; then # Check if we're in the Cuberite directory...
+ STATE_NEW=0
+elif [ -d cuberite ]; then # If there's a directory named "cuberite"...
+ cd cuberite
+ if checkCuberiteDir; then # Check if we're in the Cuberite directory...
+ STATE_NEW=0
+ else
+ errorOther "A directory is named 'cuberite' which has no Cuberite assets exists. Please run the script elsewhere or move/delete that directory."
+ fi
+
+fi
+
+if [ $STATE_NEW -eq 0 ]; then
+ echoInt "Cuberite repository detected. This should make the process faster, especially if you compiled before."
+fi
# Echo: Greetings.
-echo "
+echoInt "
+
Hello, this script will download and compile Cuberite.
On subsequent runs, it will update Cuberite.
The compilation and download will occur in the current directory.
@@ -44,84 +188,102 @@ Compiling from source takes time, but it usually generates faster
executables. If you prefer ready-to-use binaries or if you want
more info, please visit: http://cuberite.org/"
-### Dependency checks start. ###
-MISSING_PACKAGES=""
+doDependencyCheck()
+{
+ MISSING_PACKAGES=""
-# Most distros have the following default package and executable names.
-GCC_EXE_NAME="g++"
-CLANG_EXE_NAME="clang"
-COMPILER_PACKAGE_NAME="gcc g++"
+ # Most distros have the following default compiler names.
+ GCC_EXE_NAME="g++"
+ CLANG_EXE_NAME="clang"
+ COMPILER_PACKAGE_NAME="gcc g++"
-# Left side: Executable Name, Right side: Package Name. Note that this is TAB delimited. Spaces will not work.
-PROGRAMS='git git
-make make
-cmake cmake'
+ # Most distros have the following package and executable names.
+ # Left side: Executable Name, Right side: Package Name. Note that this is SPACE delimited now, unlike in the past.
+ PROGRAMS='git git
+ make make
+ cmake cmake'
-# If any OS deviates from the defaults, detect the OS here, and change PROGRAMS, COMPILER_PACKAGE_NAME, etc. as needed.
+ # If any OS deviates from the defaults, we detect the OS here, and change PROGRAMS, COMPILER_PACKAGE_NAME, etc. as needed.
-# Fedora, CentOS, RHEL, Mageia, openSUSE, Mandriva
-if (rpm --help > /dev/null 2> /dev/null); then
- COMPILER_PACKAGE_NAME="gcc-c++"
-fi
+ # Fedora, CentOS, RHEL, Mageia, openSUSE, Mandriva.
+ if (rpm --help > /dev/null 2> /dev/null); then
+ COMPILER_PACKAGE_NAME="gcc-c++"
+ fi
-# Compiler check.
-GCC_EXISTS=0
-CLANG_EXISTS=0
-$GCC_EXE_NAME --help > /dev/null 2> /dev/null && GCC_EXISTS=1
-$CLANG_EXE_NAME --help > /dev/null 2> /dev/null && CLANG_EXISTS=1
-if [ "$GCC_EXISTS" -eq 0 ] && [ "$CLANG_EXISTS" -eq 0 ]; then
- MISSING_PACKAGES=" $COMPILER_PACKAGE_NAME"
-fi
+ # Make sure at least one compiler exists.
+ GCC_EXISTS=0
+ CLANG_EXISTS=0
+ $GCC_EXE_NAME --help > /dev/null 2> /dev/null && GCC_EXISTS=1
+ $CLANG_EXE_NAME --help > /dev/null 2> /dev/null && CLANG_EXISTS=1
+ if [ "$GCC_EXISTS" -eq 0 ] && [ "$CLANG_EXISTS" -eq 0 ]; then
+ MISSING_PACKAGES=" $COMPILER_PACKAGE_NAME"
+ fi
-# Depdendency check.
-checkPackages ()
-{
- # note that IFS is a TAB here!
- echo "$PROGRAMS" | while IFS=' ' read EXE_NAME PACKAGE_NAME __trash__; do
- command -v $EXE_NAME > /dev/null 2> /dev/null || printf %s " $PACKAGE_NAME"
- done
+ # Depdendency check.
+ checkPackages ()
+ {
+ echo "$PROGRAMS" | while read line; do
+ EXE_NAME=`echo "$line" | cut -f 1 -d " "`
+ PACKAGE_NAME=`echo "$line" | cut -f 2 -d " "`
+ command -v $EXE_NAME > /dev/null 2> /dev/null || printf %s " $PACKAGE_NAME"
+ done
+ }
+ MISSING_PACKAGES="$MISSING_PACKAGES`checkPackages`"
+ missingDepsExit ()
+ {
+ if [ "$1" != "" ]; then
+ echoErr "You can install the missing depndencies via:"
+ echoErr "$1"
+ fi
+ echoErr
+ echoErr "Please install the dependencies, then come back."
+ echoErr
+ errorDependencies
+ }
+
+ if [ "$MISSING_PACKAGES" != "" ]; then
+ echoInt
+ echoInt "-----------------"
+ echoErr "You have missing compilation dependencies:"
+ echoErr $MISSING_PACKAGES
+ echoErr
+
+ # apt-get guide.
+ apt-get --help > /dev/null 2> /dev/null && \
+ missingDepsExit "sudo apt-get install$MISSING_PACKAGES"
+
+ # yum guide.
+ yum --help > /dev/null 2> /dev/null && \
+ missingDepsExit "sudo yum install$MISSING_PACKAGES"
+
+ # zypper guide.
+ zypper --help > /dev/null 2> /dev/null && \
+ missingDepsExit "sudo zypper install$MISSING_PACKAGES"
+
+ # pacman guide.
+ pacman --help > /dev/null 2> /dev/null && \
+ missingDepsExit "sudo pacman -S$MISSING_PACKAGES"
+
+ # urpmi guide.
+ urpmi --help > /dev/null 2> /dev/null && \
+ missingDepsExit "sudo urpmi$MISSING_PACKAGES"
+
+ missingDepsExit ""
+ fi
}
-MISSING_PACKAGES="$MISSING_PACKAGES`checkPackages`"
-
-if [ "$MISSING_PACKAGES" != "" ]; then
- echo
- echo "-----------------"
- echo "You have missing compilation dependencies:"
- echo $MISSING_PACKAGES
- echo
-
- # apt-get guide.
- apt-get --help > /dev/null 2> /dev/null && \
- missingDepsExit "sudo apt-get install $MISSING_PACKAGES"
-
- # yum guide.
- yum --help > /dev/null 2> /dev/null && \
- missingDepsExit "sudo yum install $MISSING_PACKAGES"
+doDependencyCheck
- # zypper guide.
- zypper --help > /dev/null 2> /dev/null && \
- missingDepsExit "sudo zypper install $MISSING_PACKAGES"
- # pacman guide.
- pacman --help > /dev/null 2> /dev/null && \
- missingDepsExit "sudo pacman -S $MISSING_PACKAGES"
+#=================== Choice: Branch (Currently unused and simply skipped) ===================
- # urpmi guide.
- urpmi --help > /dev/null 2> /dev/null && \
- missingDepsExit "sudo urpmi $MISSING_PACKAGES"
-
- missingDepsExit ""
-fi
-### Dependency checks end. ###
# Bypass Branch choice and choose master. Because it's the only branch right now.
-BRANCH="master"
+CHOICE_BRANCH=$DEFAULT_BRANCH
### Inactive code start. ###
inactiveCode ()
{
-# Echo: Branch choice.
echo "
You can choose between 3 branches:
* (S)Stable: Choose the stable branch if you want the most
@@ -136,75 +298,135 @@ You can choose between 3 branches:
"
-# Input: Branch choice.
printf %s "Choose the branch (s/t/d): "
-read BRANCH
-case $BRANCH in
+read CHOICE_BRANCH
+case $CHOICE_BRANCH in
s|S)
- error "We don't have a stable branch yet, please use testing, sorry."
+ errorOther "We don't have a stable branch yet, please use testing, sorry."
;;
t|T)
- BRANCH="testing"
+ CHOICE_BRANCH="testing"
;;
d|D)
- BRANCH="master"
+ CHOICE_BRANCH="master"
;;
*)
- error "Unrecognized user input."
+ errorInput
;;
esac
}
### Inactive code end. ###
-# Echo: Compile mode choice.
-echo "
-Choose compile mode:
-* (N)Normal: Compiles normally.
- Generates the fastest build.
-
-* (D)Debug: Compiles in debug mode.
- Makes your console and crashes more verbose.
- A bit slower than Normal mode. If you plan to help
- development by reporting bugs, this is preferred.
-
-
-Note that the script will connect to the internet in order to fetch
-code after this step. It will then compile your program.
-"
-# Input: Compile mode choice.
-printf %s "Choose compile mode: (n/d): "
-read BUILDTYPE
-case $BUILDTYPE in
- d|D)
- BUILDTYPE="Debug"
- ;;
- n|N)
- BUILDTYPE="Release"
- ;;
- *)
- error "Unrecognized user input."
- ;;
-esac
+#=================== Choice: Compile mode ===================
+
+
+if [ $STATE_INTERACTIVE -eq 1 ]; then
+ echo "
+ Choose compile mode:
+ * (R)Release: Compiles normally.
+ Generates the fastest build.
+
+ * (D)Debug: Compiles in debug mode.
+ Makes your console and crashes more verbose.
+ A bit slower than Release mode. If you plan to help
+ development by reporting bugs, this is preferred.
+
+ "
+
+ printf %s "Choose compile mode: (r/d) (Default: \"$DEFAULT_BUILDTYPE\"): "
+ read CHOICE_BUILDTYPE
+ case $CHOICE_BUILDTYPE in
+ d|D)
+ CHOICE_BUILDTYPE="Debug"
+ ;;
+ r|N)
+ CHOICE_BUILDTYPE="Release"
+ ;;
+ ""|N)
+ CHOICE_BUILDTYPE="$DEFAULT_BUILDTYPE"
+ ;;
+ *)
+ errorInput
+ ;;
+ esac
+elif [ -z "$CHOICE_BUILDTYPE" ]; then
+ CHOICE_BUILDTYPE="$DEFAULT_BUILDTYPE" # Non interactive mode with no buildtype specified.
+fi
-# Echo: Downloading began.
-echo
-echo " --- Downloading Cuberite's source code from the $BRANCH branch..."
+#=================== Choice: Thread amount ===================
-if [ ! -d cuberite ]; then
+
+autoChooseThreads()
+{
+ echo "$DEFAULT_THREADS" # Todo choose based on system info, and fallback to DEFAULT_THREADS.
+}
+
+if [ $STATE_INTERACTIVE -eq 1 ]; then
+ printf %s "Enter the number of threads to use. Leave empty for an automatic choice: "
+ read CHOICE_THREADS
+ if [ "$CHOICE_THREADS" = "" ] 2> /dev/null; then
+ CHOICE_THREADS=`autoChooseThreads`
+ elif [ "$CHOICE_THREADS" -lt 0 ] 2> /dev/null; then
+ errorInput
+ fi
+
+elif [ -z "$CHOICE_THREADS" ]; then .
+ CHOICE_THREADS=`autoChooseThreads` # Non interactive mode with no thread amount specified.
+fi
+
+
+#=================== Print settings summary ===================
+
+
+if [ "$STATE_NEW" = 1 ]; then
+ previousCompilation="Not detected. We are assuming this is the first compile.sh run."
+else
+ previousCompilation="Detected. This should make fetching and compiling faster."
+fi
+
+# Ask the user's permission to connect to the net.
+echo ""
+echoInt "#### Settings Summary ####"
+echo "Build Type: " "$CHOICE_BUILDTYPE"
+echo "Branch: " "$CHOICE_BRANCH" "(Currently the only choice)"
+echo "Compilation threads: " "$CHOICE_THREADS"
+echo "Previous compilation: " "$previousCompilation"
+echo "Upstream Link: " "$UPSTREAM_LINK"
+echo "Upstream Repo: " "$UPSTREAM_REPO"
+
+if [ "$DRY_RUN" = "yes" ]; then exit 0; fi
+
+if [ $STATE_INTERACTIVE -eq 1 ]; then
+ echo
+ echo "After pressing ENTER, the script will connect to $UPSTREAM_LINK"
+ echo "to check for updates and/or fetch code. It will then compile your program."
+ echo "If you compiled before, make sure you're in the proper directory and that \"Previous compilation\" is detected."
+ printf $s "Press ENTER to continue... "
+ read dummy
+fi
+
+
+#=================== Code download / update via git ===================
+
+
+echoInt
+echoInt " --- Downloading Cuberite's source code from the $CHOICE_BRANCH branch..."
+
+
+if [ $STATE_NEW -eq 1 ]; then
# Git: Clone.
echo " --- Looks like your first run, cloning the whole code..."
- git clone --depth 1 https://github.com/cuberite/cuberite.git -b "$BRANCH"
+ git clone --depth 1 "$UPSTREAM_LINK" -b "$CHOICE_BRANCH" || errorGit "git clone --depth 1 $UPSTREAM_LINK -b $CHOICE_BRANCH"
cd cuberite
else
# Git: Fetch.
- cd cuberite
- echo " --- Updating the $BRANCH branch..."
- git fetch origin "$BRANCH" || error "git fetch failed"
- git checkout "$BRANCH" || error "git checkout failed"
- git merge "origin/$BRANCH" || error "git merge failed"
+ echo " --- Updating the $CHOICE_BRANCH branch..."
+ git fetch "$UPSTREAM_REPO" "$CHOICE_BRANCH" || errorGit "git fetch $UPSTREAM_REPO $CHOICE_BRANCH"
+ git checkout "$CHOICE_BRANCH" || errorGit "git checkout $CHOICE_BRANCH"
+ git merge "$UPSTREAM_REPO"/"$CHOICE_BRANCH" || errorGit "git merge $UPSTREAM_REPO/$CHOICE_BRANCH"
fi
# Git: Submodules.
@@ -212,31 +434,38 @@ echo " --- Updating submodules..."
git submodule update --init
+#=================== Compilation via cmake and make ===================
+
+
# Cmake.
echo " --- Running cmake..."
if [ ! -d build-cuberite ]; then mkdir build-cuberite; fi
cd build-cuberite
-cmake .. -DCMAKE_BUILD_TYPE="$BUILDTYPE" || error "cmake failed"
+cmake .. -DCMAKE_BUILD_TYPE="$CHOICE_BUILDTYPE" || errorCompile "cmake .. -DCMAKE_BUILD_TYPE=$CHOICE_BUILDTYPE"
# Make.
echo " --- Compiling..."
-make -j 2 || error "Compiling failed"
+make -j "$CHOICE_THREADS" || errorCompile "make -j $CHOICE_THREADS"
echo
-# Echo: Compilation complete.
+#=================== Print success message ===================
+
+
cd ../Server
echo
echo "-----------------"
echo "Compilation done!"
echo
echo "Cuberite awaits you at:"
-if [ "$BUILDTYPE" = "Debug" ]; then
+
+if [ "$CHOICE_BUILDTYPE" = "Debug" ]; then
echo "$PWD/Cuberite_debug"
else
echo "$PWD/Cuberite"
fi
+
cd ..
echo "
You can always update Cuberite by executing:
@@ -245,9 +474,13 @@ You can always update Cuberite by executing:
Enjoy :)"
exit 0
+
+#=================== Windows fallback ===================
+
+
+# Called via hack in line 2.
:windows_detected
@echo off
-rem Putting echo "Foo" in Windows CMD gives you "Foo" -- with quotes.
echo This script is not available for Windows yet, sorry.
echo You can still download the Windows binaries from: http://cuberite.org
echo You can also manually compile for Windows. See: https://github.com/cuberite/cuberite