439 lines
13 KiB
Bash
Executable File
439 lines
13 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
|
|
set -e
|
|
|
|
# --- Defaults ---
|
|
userFlag=0
|
|
testsFlag=0
|
|
runTestsFlag=0
|
|
buildDir="build"
|
|
installDir="$HOME/.local/4DSSE"
|
|
|
|
|
|
# --- Help Menu ---
|
|
show_help() {
|
|
cat <<EOF
|
|
Usage: $(basename "$0") [OPTIONS]
|
|
|
|
Options:
|
|
--user Build and Install as a release for. Intended for end users.
|
|
--noBuildTest Do not build tests.
|
|
--runTest Run tests.
|
|
--buildDir Specify the build directory. Default is "${buildDir}".
|
|
--installDir Specify the install directory. Default is "${installDir}".
|
|
-h, --help Show this help message and exit
|
|
|
|
You can use these flags in any order. Flags not passed will get default values.
|
|
|
|
Examples:
|
|
For an end user who wants a seamless experience 4DSSE:
|
|
./mk --user
|
|
For developers who want to modify the source:
|
|
./mk
|
|
For developers who want to run tests:
|
|
./mk --tests
|
|
EOF
|
|
}
|
|
|
|
# --- Parse Arguments ---
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--user)
|
|
userFlag=1
|
|
shift
|
|
;;
|
|
--noTest)
|
|
testsFlag=1
|
|
shift
|
|
;;
|
|
--runTest)
|
|
runTestsFlag=1
|
|
shift
|
|
;;
|
|
--buildDir)
|
|
buildDir=1
|
|
shift
|
|
;;
|
|
--installDir)
|
|
installDir=1
|
|
shift
|
|
;;
|
|
-h|--help)
|
|
show_help
|
|
exit 0
|
|
;;
|
|
*)
|
|
echo "Unknown option: $1"
|
|
echo "Use --help for usage information."
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
RED="\033[0;31m"
|
|
GREEN="\033[0;32m"
|
|
YELLOW="\033[0;33m"
|
|
BLUE="\033[0;34m"
|
|
MAGENTA="\033[0;35m"
|
|
NC="\033[0m" # No Color
|
|
|
|
# Log file.
|
|
LOGDIR="4DSSE_logs"
|
|
if [[ ! -d "$LOGDIR" ]]; then
|
|
echo -e "${BLUE}[Info] Creating log directory...${NC}"
|
|
mkdir "$LOGDIR"
|
|
else
|
|
echo -e "${MAGENTA}[Success] Log directory already exists. Skipping...${NC}"
|
|
fi
|
|
LOGFILE="${LOGDIR}/4DSSE-install-log.txt"
|
|
|
|
|
|
# Log function: prints to stdout and appends to logfile.
|
|
log() {
|
|
local message="$1"
|
|
# Print the colored message to stdout.
|
|
echo -e "$message"
|
|
# Strip ANSI escape sequences and append the cleaned message to the log file.
|
|
echo -e "$message" | sed -r 's/\x1B\[[0-9;]*[mK]//g' >> "$LOGFILE"
|
|
}
|
|
|
|
if [[ -f "$LOGFILE" ]]; then
|
|
# Get the calendar datetime of the log file creation.
|
|
# convert UNIX timestamp to human-readable date
|
|
rm "$LOGFILE"
|
|
log "${BLUE}[Info] Old log file removed.${NC}"
|
|
fi
|
|
touch "$LOGFILE"
|
|
|
|
# --- Check if Clang or GCC is installed ---
|
|
log "${BLUE}[Info] Checking if Clang or GCC is installed...${NC}"
|
|
if ! command -v clang &> /dev/null && ! command -v gcc &> /dev/null; then
|
|
log "${RED}[Error] Clang or GCC is not installed. Exiting...${NC}"
|
|
log "${YELLOW}[Info] Please install Clang or GCC and try again.${NC}"
|
|
exit 1
|
|
else
|
|
log "${MAGENTA}[Success] Clang or GCC is installed. Continuing...${NC}"
|
|
fi
|
|
|
|
# --- Check if MESON is installed ---
|
|
log "${BLUE}[Info] Checking if Meson is installed...${NC}"
|
|
if ! command -v meson &> /dev/null; then
|
|
log "${RED}[Error] Meson is not installed. Exiting...${NC}"
|
|
# Check if the user would like to try to install meson by getting input
|
|
installMeson=0
|
|
while true; do
|
|
echo -ne "${YELLOW}[Query] Would you like to try to install Meson? [y/n]: ${NC}"
|
|
read -p "" yn
|
|
case $yn in
|
|
[Yy]* ) installMeson=1; break;;
|
|
[Nn]* ) break;;
|
|
* ) echo "Please answer yes or no.";;
|
|
esac
|
|
done
|
|
if [[ $installMeson -eq 1 ]]; then
|
|
# check if pip is installed
|
|
if ! command -v pip &> /dev/null; then
|
|
log "${RED}[Error] pip is not installed. Exiting...${NC}"
|
|
log "${YELLOW}[Info] Please install pip and try again.${NC}"
|
|
exit 1
|
|
else
|
|
log "${MAGENTA}[Success] pip is installed. Continuing...${NC}"
|
|
fi
|
|
|
|
# check if python3 is installed
|
|
if ! command -v python3 &> /dev/null; then
|
|
log "${RED}[Error] python3 is not installed. Exiting...${NC}"
|
|
log "${YELLOW}[Info] Please install python3 and try again.${NC}"
|
|
log "${YELLOW}[INFO] If you have python3 installed, please add it to your PATH.${NC}"
|
|
exit 1
|
|
else
|
|
log "${MAGENTA}[Success] python3 is installed. Continuing...${NC}"
|
|
fi
|
|
|
|
# Check if the venv ~/.4DSSE_env exists
|
|
if [[ ! -d "$HOME/.4DSSE_env" ]]; then
|
|
log "${BLUE}[Info] Creating virtual environment...${NC}"
|
|
python3 -m venv "$HOME/.4DSSE_env"
|
|
source "$HOME/.4DSSE_env/bin/activate"
|
|
log "${GREEN}[Success] Virtual environment created.${NC}"
|
|
else
|
|
log "${MAGENTA}[Success] Virtual environment already exists. Skipping...${NC}"
|
|
fi
|
|
|
|
# install meson
|
|
log "${BLUE}[Info] Installing Meson...${NC}"
|
|
pip install meson
|
|
|
|
# confirm meson is installed
|
|
if ! command -v meson &> /dev/null; then
|
|
log "${RED}[Error] Meson did not install properly. Exiting...${NC}"
|
|
log "${YELLOW}[Info] Please manually install Meson and try again.${NC}"
|
|
exit 1
|
|
else
|
|
log "${GREEN}[Success] Meson installed.${NC}"
|
|
fi
|
|
else
|
|
log "${YELLOW}[Info] Please install Meson and try again.${NC}"
|
|
exit 1
|
|
fi
|
|
else
|
|
log "${MAGENTA}[Success] Meson is installed. Continuing...${NC}"
|
|
fi
|
|
|
|
# --- Check if NINJA is installed ---
|
|
log "${BLUE}[Info] Checking if Ninja is installed...${NC}"
|
|
if ! command -v ninja &> /dev/null; then
|
|
log "${RED}[Error] Ninja is not installed. Exiting...${NC}"
|
|
|
|
# Check if the user would like to try to install ninja by getting input
|
|
installNinja=0
|
|
while true; do
|
|
echo -ne "${YELLOW}[Query] Would you like to try to install Ninja? [y/n]: ${NC}"
|
|
read -p "" yn
|
|
case $yn in
|
|
[Yy]* ) installNinja=1; break;;
|
|
[Nn]* ) break;;
|
|
* ) echo "Please answer yes or no.";;
|
|
esac
|
|
done
|
|
if [[ $installNinja -eq 1 ]]; then
|
|
# check if pip is installed
|
|
if ! command -v pip &> /dev/null; then
|
|
log "${RED}[Error] pip is not installed. Exiting...${NC}"
|
|
log "${YELLOW}[Info] Please install pip and try again.${NC}"
|
|
exit 1
|
|
else
|
|
log "${MAGENTA}[Success] pip is installed. Continuing...${NC}"
|
|
fi
|
|
|
|
# check if python3 is installed
|
|
if ! command -v python3 &> /dev/null; then
|
|
log "${RED}[Error] python3 is not installed. Exiting...${NC}"
|
|
log "${YELLOW}[Info] Please install python3 and try again.${NC}"
|
|
log "${YELLOW}[INFO] If you have python3 installed, please add it to your PATH.${NC}"
|
|
exit 1
|
|
else
|
|
log "${MAGENTA}[Success] python3 is installed. Continuing...${NC}"
|
|
fi
|
|
|
|
# Check if the venv ~/.4DSSE_env exists
|
|
if [[ ! -d "$HOME/.4DSSE_env" ]]; then
|
|
log "${BLUE}[Info] Creating virtual environment...${NC}"
|
|
python3 -m venv "$HOME/.4DSSE_env"
|
|
source "$HOME/.4DSSE_env/bin/activate"
|
|
log "${GREEN}[Success] Virtual environment created.${NC}"
|
|
else
|
|
log "${MAGENTA}[Success] Virtual environment already exists. Skipping...${NC}"
|
|
fi
|
|
|
|
# install ninja
|
|
log "${BLUE}[Info] Installing Ninja...${NC}"
|
|
pip install ninja
|
|
|
|
# confirm ninja is installed
|
|
if ! command -v ninja &> /dev/null; then
|
|
log "${RED}[Error] Ninja did not install properly. Exiting...${NC}"
|
|
log "${YELLOW}[Info] Please manually install Ninja and try again.${NC}"
|
|
exit 1
|
|
else
|
|
log "${GREEN}[Success] Ninja installed.${NC}"
|
|
fi
|
|
else
|
|
log "${YELLOW}[Info] Please install Ninja and try again.${NC}"
|
|
exit 1
|
|
fi
|
|
else
|
|
log "${MAGENTA}[Success] Ninja is installed. Continuing...${NC}"
|
|
fi
|
|
|
|
# --- Check if CMake is installed ---
|
|
log "${BLUE}[Info] Checking if CMake is installed...${NC}"
|
|
if ! command -v cmake &> /dev/null; then
|
|
log "${RED}[Error] CMake is not installed....${NC}"
|
|
|
|
# Check if the user would like to try to install cmake by getting input
|
|
installCMake=0
|
|
while true; do
|
|
echo -ne "${YELLOW}[Query] Would you like to try to install CMake? [y/n]: ${NC}"
|
|
read -p "" yn
|
|
case $yn in
|
|
[Yy]* ) installCMake=1; break;;
|
|
[Nn]* ) break;;
|
|
* ) echo "Please answer yes or no.";;
|
|
esac
|
|
done
|
|
if [[ $installCMake -eq 1 ]]; then
|
|
# check if pip is installed
|
|
if ! command -v pip &> /dev/null; then
|
|
log "${RED}[Error] pip is not installed. Exiting...${NC}"
|
|
log "${YELLOW}[Info] Please install pip and try again.${NC}"
|
|
exit 1
|
|
else
|
|
log "${MAGENTA}[Success] pip is installed. Continuing...${NC}"
|
|
fi
|
|
|
|
# check if python3 is installed
|
|
if ! command -v python3 &> /dev/null; then
|
|
log "${RED}[Error] python3 is not installed. Exiting...${NC}"
|
|
log "${YELLOW}[Info] Please install python3 and try again.${NC}"
|
|
log "${YELLOW}[INFO] If you have python3 installed, please add it to your PATH.${NC}"
|
|
exit 1
|
|
else
|
|
log "${MAGENTA}[Success] python3 is installed. Continuing...${NC}"
|
|
fi
|
|
|
|
# Check if the venv ~/.4DSSE_env exists
|
|
if [[ ! -d "$HOME/.4DSSE_env" ]]; then
|
|
log "${BLUE}[Info] Creating virtual environment...${NC}"
|
|
python3 -m venv "$HOME/.4DSSE_env"
|
|
source "$HOME/.4DSSE_env/bin/activate"
|
|
log "${GREEN}[Success] Virtual environment created.${NC}"
|
|
else
|
|
log "${MAGENTA}[Success] Virtual environment already exists. Skipping...${NC}"
|
|
fi
|
|
|
|
# install cmake
|
|
log "${BLUE}[Info] Installing CMake...${NC}"
|
|
pip install cmake
|
|
|
|
# confirm cmake is installed
|
|
if ! command -v cmake &> /dev/null; then
|
|
log "${RED}[Error] CMake did not install properly. Exiting...${NC}"
|
|
log "${YELLOW}[Info] Please manually install CMake and try again.${NC}"
|
|
exit 1
|
|
else
|
|
log "${GREEN}[Success] CMake installed.${NC}"
|
|
fi
|
|
fi
|
|
else
|
|
log "${MAGENTA}[Success] CMake is installed. Continuing...${NC}"
|
|
fi
|
|
|
|
# --- Build 4DSSE ---
|
|
log "${BLUE}[Info] Building 4DSSE...${NC}"
|
|
if [[ $userFlag -eq 1 ]]; then
|
|
log "${BLUE}[Info] Installing 4DSSE in user mode...${NC}"
|
|
else
|
|
log "${BLUE}[Info] Installing 4DSSE for developers...${NC}"
|
|
fi
|
|
|
|
if [[ $testsFlag -eq 0 ]]; then
|
|
log "${BLUE}[Info] Building with tests...${NC}"
|
|
else
|
|
log "${BLUE}[Info] Building without tests...${NC}"
|
|
fi
|
|
|
|
# --- First check Boost status ---
|
|
log "${BLUE}[Info] Checking Boost status...${NC}"
|
|
# if the following script exists with anything other than a 0 status the script will exit
|
|
if [[ -f ./build-config/boost/.boost_installed ]]; then
|
|
log "${MAGENTA}[Success] Boost already installed. Skipping...${NC}"
|
|
else
|
|
log "${BLUE}[Info] Installing Boost...${NC}"
|
|
if ! ./build-config/boost/install.sh; then
|
|
log "${RED}[Error] Boost check failed. Exiting...${NC}"
|
|
exit 1
|
|
else
|
|
touch ./build-config/boost/.boost_installed
|
|
log "${GREEN}[Success] Boost check passed.${NC}"
|
|
fi
|
|
fi
|
|
|
|
## --- Check if MPI is installed ---
|
|
log "${BLUE}[Info] Checking MPI status...${NC}"
|
|
# if the following script exists with anything other than a 0 status the script will exit
|
|
if [[ -f ./build-config/mpi/.mpi_installed ]]; then
|
|
log "${MAGENTA}[Success] MPI already installed. Skipping...${NC}"
|
|
else
|
|
log "${BLUE}[Info] Installing MPI...${NC}"
|
|
if ! ./build-config/mpi/install.sh; then
|
|
log "${RED}[Error] MPI check failed. Exiting...${NC}"
|
|
exit 1
|
|
else
|
|
touch ./build-config/mpi/.mpi_installed
|
|
log "${GREEN}[Success] MPI check passed.${NC}"
|
|
fi
|
|
fi
|
|
|
|
|
|
#check if the last build flags are the same as the current build flags
|
|
# if the flags are the same skip the configuration step
|
|
# if they are different then reconfigure the build directory
|
|
|
|
# do not use grep -oP as it is not POSIX compliant
|
|
|
|
doReconfigure=1
|
|
|
|
log "${BLUE}[Info] Checking last build flags...${NC}"
|
|
if [[ -f $buildDir/.last_build_flags ]]; then
|
|
lastUserFlag=$(grep -Eo 'userFlag=[0-9]+' $buildDir/.last_build_flags | cut -d'=' -f2)
|
|
lastTestsFlag=$(grep -Eo 'testsFlag=[0-9]+' $buildDir/.last_build_flags | cut -d'=' -f2)
|
|
if [[ $lastUserFlag -eq $userFlag && $lastTestsFlag -eq $testsFlag ]]; then
|
|
log "${MAGENTA}[Success] Last build flags match current build flags. Skipping configuration...${NC}"
|
|
doReconfigure=0
|
|
else
|
|
log "${YELLOW}[Info] Last build flags do not match current build flags. Reconfiguring...${NC}"
|
|
rm -rf $buildDir
|
|
fi
|
|
else
|
|
log "${BLUE}[Info] Last build flags not found. Reconfiguring...${NC}"
|
|
fi
|
|
|
|
|
|
# --- Check if the build dir has been configured with the correct flags ---
|
|
if [[ $doReconfigure -eq 1 ]]; then
|
|
log "${BLUE}[Info] Configuring build directory...${NC}"
|
|
if [ -f "$buildDir/build.ninja" ]; then
|
|
log "${MAGENTA}[Success] Build directory already configured. Skipping...${NC}"
|
|
else
|
|
if [[ $userFlag -eq 1 ]]; then
|
|
meson setup "$buildDir" -Duser_mode=true --buildtype=release
|
|
else
|
|
if [[ $testsFlag -eq 0 ]]; then
|
|
meson setup "$buildDir" --buildtype=debug
|
|
else
|
|
meson setup "$buildDir" --buildtype=debug -Dbuild_tests=false
|
|
fi
|
|
fi
|
|
log "${GREEN}[Success] Build directory configured successfully.${NC}"
|
|
fi
|
|
log "${BLUE}[Info] Caching last build flags...${NC}"
|
|
|
|
# --- Cache the last build flags ---
|
|
if [[ $userFlag -eq 1 ]]; then
|
|
echo "userFlag=1" > $buildDir/.last_build_flags
|
|
else
|
|
echo "userFlag=0" > $buildDir/.last_build_flags
|
|
fi
|
|
if [[ $testsFlag -eq 1 ]]; then
|
|
echo "testsFlag=1" >> $buildDir/.last_build_flags
|
|
else
|
|
echo "testsFlag=0" >> $buildDir/.last_build_flags
|
|
fi
|
|
|
|
log "${GREEN}[Success] Last build flags cached.${NC}"
|
|
fi
|
|
|
|
log "${BLUE}[Info] Building 4DSSE...${NC}"
|
|
meson compile -C "$buildDir"
|
|
|
|
# --- Install 4DSSE ---
|
|
if [[ $userFlag -eq 1 ]]; then
|
|
log "${BLUE}[Info] Installing 4DSSE in user mode...${NC}"
|
|
meson install -C "$buildDir"
|
|
fi
|
|
|
|
if [[ $runTestsFlag -eq 1 ]]; then
|
|
log "${BLUE}[Info] Running tests...${NC}"
|
|
meson test -C "$buildDir"
|
|
fi
|
|
|
|
if [[ $userFlag -eq 1 ]]; then
|
|
log "${GREEN}[Success] 4DSSE built and installed successfully.${NC}"
|
|
else
|
|
log "${GREEN}[Success] 4DSSE built successfully.${NC}"
|
|
fi
|
|
|
|
|
|
log "${GREEN}[Success] 4DSSE mk script complete.${NC}"
|