build(installed): added more options and better tui mode

This commit is contained in:
2025-07-29 09:25:44 -04:00
parent f5328785a8
commit 89d9472080
3 changed files with 349 additions and 182 deletions

View File

@@ -33,6 +33,21 @@ only and do not necessarily reflect those of the European Union or the European
## Build and Installation Instructions ## Build and Installation Instructions
The easiest way to build GridFire is using the `install.sh` or `install-tui.sh` scripts in the root directory. To use
these scripts, simply run:
```bash
./install.sh
# or
./install-tui.sh
```
The regular installation script will select a standard "ideal" set of build options for you. If you want more control
over the build options, you can use the `install-tui.sh` script, which will provide a text-based user interface to
select the build options you want.
Generally, both are intended to be easy to use and will prompt you automatically to install any missing dependencies.
### Prerequisites ### Prerequisites
- C++ compiler supporting C++23 standard - C++ compiler supporting C++23 standard
- Meson build system (>= 1.5.0) - Meson build system (>= 1.5.0)

3
install-tui.sh Executable file
View File

@@ -0,0 +1,3 @@
#!/bin/bash
./install.sh --tui

View File

@@ -1,26 +1,28 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# #
# install.sh - Comprehensive interactive installation script for GridFire # install.sh - Comprehensive interactive installation script for GridFire.
# #
# This script performs the following actions: # This script performs the following actions:
# 1. Checks for essential system dependencies: # 1. Checks for essential system dependencies.
# - A C++ compiler (g++ or clang++) # 2. If run with the --tui flag, it provides a comprehensive text-based user interface
# - Python 3 development headers # to select and install dependencies, configure the build, and run build steps.
# - CMake
# - Meson
# - Boost libraries
# 2. If run with the --tui flag, it provides a text-based user interface
# to select and install missing dependencies.
# 3. If run without flags, it prompts the user interactively for each missing dependency. # 3. If run without flags, it prompts the user interactively for each missing dependency.
# 4. Provides detailed installation instructions for various Linux distributions and macOS. # 4. Provides detailed installation instructions for various Linux distributions and macOS.
# 5. Once all dependencies are met, it runs the meson setup and build commands. # 5. Once all dependencies are met, it can run the meson setup, compile, install, and test commands.
# 6. Logs all operations to a file for easy debugging. # 6. Logs all operations to a file for easy debugging.
set -o pipefail set -o pipefail
# --- Configuration --- # --- Configuration ---
LOGFILE="GridFire_Installer.log" LOGFILE="GridFire_Installer.log"
# --- Build Configuration Globals ---
BUILD_DIR="build" BUILD_DIR="build"
INSTALL_PREFIX="/usr/local"
MESON_BUILD_TYPE="release"
MESON_LOG_LEVEL="info"
MESON_PKG_CONFIG="true"
MESON_NUM_CORES=$(getconf _NPROCESSORS_ONLN 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 1)
# --- ANSI Color Codes --- # --- ANSI Color Codes ---
RED="\033[0;31m" RED="\033[0;31m"
@@ -61,7 +63,7 @@ show_help() {
echo "This script checks for dependencies, installs them, and builds the project." echo "This script checks for dependencies, installs them, and builds the project."
echo echo
echo "Options:" echo "Options:"
echo " --tui Run in Text-based User Interface mode for interactive dependency installation." echo " --tui Run in Text-based User Interface mode for interactive dependency installation and build control."
echo " --help, -h Show this help message and exit." echo " --help, -h Show this help message and exit."
echo " --clean Remove the build directory and log file before starting." echo " --clean Remove the build directory and log file before starting."
echo echo
@@ -82,15 +84,16 @@ fi
# --- Dependency Check Functions --- # --- Dependency Check Functions ---
# Check for a C++ compiler. check_command() {
command -v "$1" &>/dev/null
}
check_compiler() { check_compiler() {
if command -v g++ &>/dev/null; then if check_command g++; then
COMPILER_CMD="g++" log "${GREEN}[OK] Found C++ compiler: g++${NC}"
log "${GREEN}[OK] Found C++ compiler: $(g++ --version | head -n1)${NC}"
return 0 return 0
elif command -v clang++ &>/dev/null; then elif check_command clang++; then
COMPILER_CMD="clang++" log "${GREEN}[OK] Found C++ compiler: clang++${NC}"
log "${GREEN}[OK] Found C++ compiler: $(clang++ --version | head -n1)${NC}"
return 0 return 0
else else
log "${RED}[FAIL] No C++ compiler (g++ or clang++) found.${NC}" log "${RED}[FAIL] No C++ compiler (g++ or clang++) found.${NC}"
@@ -98,9 +101,8 @@ check_compiler() {
fi fi
} }
# Check for Python 3 development headers.
check_python_dev() { check_python_dev() {
if python3-config --includes &>/dev/null; then if check_command python3 && python3-config --includes &>/dev/null; then
log "${GREEN}[OK] Found Python 3 development headers.${NC}" log "${GREEN}[OK] Found Python 3 development headers.${NC}"
return 0 return 0
else else
@@ -109,9 +111,8 @@ check_python_dev() {
fi fi
} }
# Check for CMake.
check_cmake() { check_cmake() {
if command -v cmake &>/dev/null; then if check_command cmake; then
log "${GREEN}[OK] Found CMake: $(cmake --version | head -n1)${NC}" log "${GREEN}[OK] Found CMake: $(cmake --version | head -n1)${NC}"
return 0 return 0
else else
@@ -120,9 +121,8 @@ check_cmake() {
fi fi
} }
# Check for Meson.
check_meson() { check_meson() {
if command -v meson &>/dev/null; then if check_command meson; then
log "${GREEN}[OK] Found Meson: $(meson --version)${NC}" log "${GREEN}[OK] Found Meson: $(meson --version)${NC}"
return 0 return 0
else else
@@ -131,17 +131,10 @@ check_meson() {
fi fi
} }
# Check if Boost is installed and available to Meson.
check_boost() { check_boost() {
log "${BLUE}[Info] Checking for Boost dependency using Meson...${NC}" log "${BLUE}[Info] Checking for Boost dependency using Meson...${NC}"
if meson introspect --dependencies -C "$BUILD_DIR" 2>/dev/null | grep -q "boost.*found: YES"; then
log "${GREEN}[OK] Boost dependency is already met in the Meson build directory.${NC}"
return 0
fi
# A simple meson dependency check as a fallback
local test_dir="meson-boost-test" local test_dir="meson-boost-test"
rm -rf "$test_dir" && mkdir "$test_dir" rm -rf "$test_dir" && mkdir -p "$test_dir"
cat > "$test_dir/meson.build" <<EOF cat > "$test_dir/meson.build" <<EOF
project('boost-check', 'cpp') project('boost-check', 'cpp')
boost_dep = dependency('boost', required: true) boost_dep = dependency('boost', required: true)
@@ -157,10 +150,8 @@ EOF
fi fi
} }
# --- Dependency Installation Functions --- # --- Dependency Installation Functions ---
# Execute an installation command.
run_install_cmd() { run_install_cmd() {
local cmd="$1" local cmd="$1"
log "${BLUE}[Exec] Running: ${cmd}${NC}" log "${BLUE}[Exec] Running: ${cmd}${NC}"
@@ -173,19 +164,21 @@ run_install_cmd() {
fi fi
} }
# Get installation command for a given dependency.
get_install_cmd() { get_install_cmd() {
local dep_name="$1" local dep_name="$1"
local cmd="" local cmd=""
case "$OS_NAME" in case "$OS_NAME" in
"macOS") "macOS")
[ ! -f /opt/homebrew/bin/brew ] && [ ! -f /usr/local/bin/brew ] && log "${YELLOW}Homebrew not found. Please install from https://brew.sh${NC}"
local brew_cmd
brew_cmd=$(command -v brew)
case "$dep_name" in case "$dep_name" in
"compiler") cmd="xcode-select --install" ;; "compiler") cmd="xcode-select --install" ;;
"python-dev") cmd="brew install python3" ;; "python-dev") cmd="$brew_cmd install python3" ;;
"cmake") cmd="brew install cmake" ;; "cmake") cmd="$brew_cmd install cmake" ;;
"meson") cmd="brew install meson" ;; "meson") cmd="$brew_cmd install meson" ;;
"boost") cmd="brew install boost" ;; "boost") cmd="$brew_cmd install boost" ;;
"dialog") cmd="brew install dialog" ;; "dialog") cmd="$brew_cmd install dialog" ;;
esac esac
;; ;;
"Linux") "Linux")
@@ -220,122 +213,103 @@ get_install_cmd() {
"dialog") cmd="sudo pacman -S --noconfirm dialog" ;; "dialog") cmd="sudo pacman -S --noconfirm dialog" ;;
esac esac
;; ;;
*) *) log "${YELLOW}[Warn] Unsupported Linux distribution: ${DISTRO_ID}.${NC}" ;;
log "${YELLOW}[Warn] Unsupported Linux distribution: ${DISTRO_ID}. Cannot provide install commands.${NC}"
;;
esac esac
;; ;;
*) *) log "${YELLOW}[Warn] Unsupported OS: ${OS_NAME}.${NC}" ;;
log "${YELLOW}[Warn] Unsupported OS: ${OS_NAME}. Cannot provide install commands.${NC}"
;;
esac esac
echo "$cmd" echo "$cmd"
} }
# --- Main Logic --- # --- Build Functions ---
# Run the Meson setup and build process. run_meson_setup() {
run_meson_build() { log "\n${BLUE}--- Configuring Meson Build ---${NC}"
log "\n${BLUE}--- Starting Meson Build ---${NC}" if [ ! -f "meson.build" ]; then
if [ ! -f "meson.build" ]; then log "${RED}[FATAL] meson.build file not found. Cannot proceed.${NC}"; return 1;
log "${RED}[FATAL] meson.build file not found in the current directory. Cannot proceed.${NC}" fi
exit 1 local reconfigure_flag=""
fi if [ -d "$BUILD_DIR" ]; then
reconfigure_flag="--reconfigure"
log "${YELLOW}[Info] Existing build directory found. Will reconfigure.${NC}"
fi
log "${BLUE}[Info] Running meson setup...${NC}" local meson_opts=()
if ! meson setup "${BUILD_DIR}"; then meson_opts+=("-Dbuildtype=${MESON_BUILD_TYPE}")
log "${RED}[FATAL] Meson setup failed. Check the output above and in ${LOGFILE} for details.${NC}" meson_opts+=("-Dlog_level=${MESON_LOG_LEVEL}")
exit 1 meson_opts+=("-Dpkg-config=${MESON_PKG_CONFIG}")
fi meson_opts+=("--prefix=${INSTALL_PREFIX}")
log "${GREEN}[Success] Meson setup complete.${NC}"
log "${BLUE}[Info] Running meson compile...${NC}" log "${BLUE}[Info] Running meson setup with options: ${meson_opts[*]}${NC}"
if ! meson compile -C "${BUILD_DIR}"; then if ! meson setup "${BUILD_DIR}" "${meson_opts[@]}" ${reconfigure_flag}; then
log "${RED}[FATAL] Meson compile failed. Check the output above and in ${LOGFILE} for details.${NC}" log "${RED}[FATAL] Meson setup failed. See log for details.${NC}"; return 1;
exit 1 fi
fi log "${GREEN}[Success] Meson setup complete.${NC}"
log "\n${GREEN}--- Build Successful! ---${NC}"
log "${GREEN}The project has been built in the '${BUILD_DIR}' directory.${NC}"
} }
# Run the TUI for dependency installation. run_meson_compile() {
run_tui() { log "\n${BLUE}--- Compiling Project ---${NC}"
if ! command -v dialog &>/dev/null; then if [ ! -d "$BUILD_DIR" ]; then
log "${YELLOW}[Warn] The 'dialog' utility is not installed. It is required for TUI mode.${NC}" log "${RED}[FATAL] Build directory not found. Run setup first.${NC}"; return 1;
fi
log "${BLUE}[Info] Running meson compile with ${MESON_NUM_CORES} cores...${NC}"
if ! meson compile -C "${BUILD_DIR}" -j "${MESON_NUM_CORES}"; then
log "${RED}[FATAL] Meson compile failed. See log for details.${NC}"; return 1;
fi
log "${GREEN}[Success] Meson compile complete.${NC}"
}
run_meson_install() {
log "\n${BLUE}--- Installing Project ---${NC}"
if [ ! -d "$BUILD_DIR" ]; then
log "${RED}[FATAL] Build directory not found. Run setup and compile first.${NC}"; return 1;
fi
log "${BLUE}[Info] Running meson install (prefix: ${INSTALL_PREFIX})...${NC}"
if ! sudo meson install -C "${BUILD_DIR}"; then
log "${RED}[FATAL] Meson install failed. See log for details.${NC}"; return 1;
fi
log "${GREEN}[Success] Meson install complete.${NC}"
}
run_meson_tests() {
log "\n${BLUE}--- Running Tests ---${NC}"
if [ ! -d "$BUILD_DIR" ]; then
log "${RED}[FATAL] Build directory not found. Run setup and compile first.${NC}"; return 1;
fi
log "${BLUE}[Info] Running meson test...${NC}"
if ! meson test -C "${BUILD_DIR}"; then
log "${RED}[FATAL] Meson tests failed. See log for details.${NC}"; return 1;
fi
log "${GREEN}[Success] Tests passed.${NC}"
}
# --- TUI Functions ---
check_dialog_installed() {
if ! check_command dialog; then
log "${YELLOW}[Warn] The 'dialog' utility is required for TUI mode.${NC}"
local install_cmd local install_cmd
install_cmd=$(get_install_cmd "dialog") install_cmd=$(get_install_cmd "dialog")
if [ -n "$install_cmd" ]; then if [ -n "$install_cmd" ]; then
if prompt_yes_no "Would you like to install it now? (y/n):"; then if prompt_yes_no "Attempt to install it now? (y/n):"; then
eval "$install_cmd" eval "$install_cmd"
if ! command -v dialog &>/dev/null; then if ! check_command dialog; then
log "${RED}[FATAL] Failed to install 'dialog'. Cannot run in TUI mode.${NC}" log "${RED}[FATAL] Failed to install 'dialog'. Cannot run in TUI mode.${NC}"
exit 1 return 1
fi fi
else else
log "${RED}[FATAL] Cannot run in TUI mode without 'dialog'. Exiting.${NC}" log "${RED}[FATAL] Cannot run in TUI mode without 'dialog'. Exiting.${NC}"
exit 1 return 1
fi fi
else else
log "${RED}[FATAL] Cannot automatically install 'dialog' on your system. Please install it manually and try again.${NC}" log "${RED}[FATAL] Cannot auto-install 'dialog'. Please install it manually.${NC}"
exit 1 return 1
fi fi
fi fi
return 0
local choices
choices=$(dialog --clear --backtitle "Project Dependency Installer" \
--title "Install Dependencies" \
--checklist "Select dependencies to install. Dependencies marked with (*) are missing." 20 70 5 \
"compiler" "C++ Compiler (g++ or clang++)" "$([[ ${DEP_STATUS[compiler]} == "FAIL" ]] && echo "on" || echo "off")" \
"python-dev" "Python 3 Dev Headers" "$([[ ${DEP_STATUS[python-dev]} == "FAIL" ]] && echo "on" || echo "off")" \
"cmake" "CMake" "$([[ ${DEP_STATUS[cmake]} == "FAIL" ]] && echo "on" || echo "off")" \
"meson" "Meson Build System" "$([[ ${DEP_STATUS[meson]} == "FAIL" ]] && echo "on" || echo "off")" \
"boost" "Boost Libraries" "$([[ ${DEP_STATUS[boost]} == "FAIL" ]] && echo "on" || echo "off")" \
3>&1 1>&2 2>&3)
clear
if [ -z "$choices" ]; then
log "${YELLOW}[Info] No dependencies selected for installation.${NC}"
return
fi
for choice in $choices; do
local dep
dep=$(echo "$choice" | tr -d '"')
log "\n${BLUE}--- Installing ${dep} ---${NC}"
local install_cmd
install_cmd=$(get_install_cmd "$dep")
if [ -n "$install_cmd" ]; then
run_install_cmd "$install_cmd"
else
log "${RED}[Error] No automatic installation command available for '${dep}' on your system.${NC}"
log "${RED}Please install it manually.${NC}"
fi
done
} }
# --- Script Entry Point --- run_dependency_installer_tui() {
main() {
# Handle command-line arguments
if [[ " $@ " =~ " --help " ]] || [[ " $@ " =~ " -h " ]]; then
show_help
exit 0
fi
if [[ " $@ " =~ " --clean " ]]; then
log "${BLUE}[Info] Cleaning up previous build...${NC}"
rm -rf "$BUILD_DIR" "$LOGFILE"
fi
# Start logging
echo "" > "$LOGFILE"
log "--- Project Installation Log ---"
log "Date: $(date)"
log "OS: ${OS_NAME}, Distro: ${DISTRO_ID}"
# Perform all dependency checks
log "\n${BLUE}--- Checking System Dependencies ---${NC}"
declare -A DEP_STATUS declare -A DEP_STATUS
check_compiler; DEP_STATUS[compiler]=$? check_compiler; DEP_STATUS[compiler]=$?
check_python_dev; DEP_STATUS[python-dev]=$? check_python_dev; DEP_STATUS[python-dev]=$?
@@ -343,68 +317,243 @@ main() {
check_meson; DEP_STATUS[meson]=$? check_meson; DEP_STATUS[meson]=$?
check_boost; DEP_STATUS[boost]=$? check_boost; DEP_STATUS[boost]=$?
local all_deps_met=0 local choices
for status in "${DEP_STATUS[@]}"; do choices=$(dialog --clear --backtitle "Project Dependency Installer" \
if [ "$status" -ne 0 ]; then --title "Install System Dependencies" \
all_deps_met=1 --checklist "Select dependencies to install. Already found dependencies are unchecked." 20 70 5 \
break "compiler" "C++ Compiler (g++ or clang++)" "$([[ ${DEP_STATUS[compiler]} -ne 0 ]] && echo "on" || echo "off")" \
"python-dev" "Python 3 Dev Headers" "$([[ ${DEP_STATUS[python-dev]} -ne 0 ]] && echo "on" || echo "off")" \
"cmake" "CMake" "$([[ ${DEP_STATUS[cmake]} -ne 0 ]] && echo "on" || echo "off")" \
"meson" "Meson Build System" "$([[ ${DEP_STATUS[meson]} -ne 0 ]] && echo "on" || echo "off")" \
"boost" "Boost Libraries" "$([[ ${DEP_STATUS[boost]} -ne 0 ]] && echo "on" || echo "off")" \
3>&1 1>&2 2>&3)
clear
if [ -z "$choices" ]; then log "${YELLOW}[Info] No dependencies selected.${NC}"; return; fi
for choice in $choices; do
local dep; dep=$(echo "$choice" | tr -d '"')
log "\n${BLUE}--- Installing ${dep} ---${NC}"
local install_cmd; install_cmd=$(get_install_cmd "$dep")
if [ -n "$install_cmd" ]; then
eval "$install_cmd" 2>&1 | tee -a "$LOGFILE"
else
log "${RED}[Error] No automatic installation command for '${dep}'. Please install manually.${NC}"
dialog --msgbox "Could not find an automatic installation command for '${dep}' on your system. Please install it manually." 8 60
fi fi
done done
}
if [ $all_deps_met -eq 0 ]; then run_python_bindings_tui() {
log "\n${GREEN}--- All dependencies are met! ---${NC}" local python_exec
run_meson_build python_exec=$(command -v python3)
if [ -z "$python_exec" ]; then
dialog --msgbox "Could not find 'python3' executable. Please ensure Python 3 is installed and in your PATH." 8 60
return
fi
local choice
choice=$(dialog --clear --backtitle "Python Bindings Installer" \
--title "Install Python Bindings" \
--menu "Using Python: ${python_exec}\n\nSelect installation mode:" 15 70 2 \
"1" "Developer Mode (pip install -e .)" \
"2" "User Mode (pip install .)" \
3>&1 1>&2 2>&3)
clear
case "$choice" in
1)
log "${BLUE}[Info] Installing Python bindings in Developer Mode...${NC}"
if ! pip install -e . --no-build-isolation -vv; then
log "${RED}[Error] Failed to install Python bindings in developer mode.${NC}"
dialog --msgbox "Developer mode installation failed. Check the log for details." 8 60
else
log "${GREEN}[Success] Python bindings installed in developer mode.${NC}"
dialog --msgbox "Successfully installed Python bindings in developer mode." 8 60
fi
;;
2)
log "${BLUE}[Info] Installing Python bindings in User Mode...${NC}"
if ! pip install .; then
log "${RED}[Error] Failed to install Python bindings in user mode.${NC}"
dialog --msgbox "User mode installation failed. Check the log for details." 8 60
else
log "${GREEN}[Success] Python bindings installed in user mode.${NC}"
dialog --msgbox "Successfully installed Python bindings in user mode." 8 60
fi
;;
*)
log "${YELLOW}[Info] Python binding installation cancelled.${NC}"
;;
esac
}
run_build_config_tui() {
local choice
choice=$(dialog --clear --backtitle "Build Configuration" \
--title "Configure Build Options" \
--menu "Select an option to configure:" 20 70 6 \
"1" "Build Directory (current: ${BUILD_DIR})" \
"2" "Install Prefix (current: ${INSTALL_PREFIX})" \
"3" "Build Type (current: ${MESON_BUILD_TYPE})" \
"4" "Log Level (current: ${MESON_LOG_LEVEL})" \
"5" "Generate pkg-config (current: ${MESON_PKG_CONFIG})" \
"6" "Number of Cores (current: ${MESON_NUM_CORES})" \
3>&1 1>&2 2>&3)
clear
case "$choice" in
1)
local new_dir
new_dir=$(dialog --title "Set Build Directory" --inputbox "Enter new build directory name:" 10 60 "${BUILD_DIR}" 3>&1 1>&2 2>&3)
if [ -n "$new_dir" ]; then
BUILD_DIR="$new_dir"
log "${BLUE}[Config] Set build directory to: ${BUILD_DIR}${NC}"
fi
;;
2)
local new_prefix
new_prefix=$(dialog --title "Set Install Prefix" --inputbox "Enter absolute path for installation prefix:" 10 60 "${INSTALL_PREFIX}" 3>&1 1>&2 2>&3)
if [ -n "$new_prefix" ]; then
INSTALL_PREFIX="$new_prefix"
log "${BLUE}[Config] Set install prefix to: ${INSTALL_PREFIX}${NC}"
fi
;;
3)
local build_type_choice
build_type_choice=$(dialog --title "Select Build Type" --menu "" 15 70 3 \
"release" "Optimized for performance" \
"debug" "With debug symbols, no optimization" \
"debugoptimized" "With debug symbols and optimization" \
3>&1 1>&2 2>&3)
if [ -n "$build_type_choice" ]; then
MESON_BUILD_TYPE="$build_type_choice"
log "${BLUE}[Config] Set build type to: ${MESON_BUILD_TYPE}${NC}"
fi
;;
4)
local log_level_choice
log_level_choice=$(dialog --title "Select Log Level" --menu "" 15 70 8 \
"traceL3" "" "traceL2" "" "traceL1" "" "debug" "" "info" "" "warning" "" "error" "" "critical" "" \
3>&1 1>&2 2>&3)
if [ -n "$log_level_choice" ]; then
MESON_LOG_LEVEL="$log_level_choice"
log "${BLUE}[Config] Set log level to: ${MESON_LOG_LEVEL}${NC}"
fi
;;
5)
if dialog --title "Generate pkg-config" --yesno "Generate gridfire.pc file?" 7 60; then
MESON_PKG_CONFIG="true"
else
MESON_PKG_CONFIG="false"
fi
log "${BLUE}[Config] Set pkg-config generation to: ${MESON_PKG_CONFIG}${NC}"
;;
6)
local max_cores; max_cores=$(getconf _NPROCESSORS_ONLN 2>/dev/null || sysctl -n hw.ncpu 2>/dev/null || echo 1)
local core_choice
core_choice=$(dialog --title "Set Number of Cores" --inputbox "Enter number of cores for compilation.\nAvailable: ${max_cores}" 10 60 "${MESON_NUM_CORES}" 3>&1 1>&2 2>&3)
if [[ "$core_choice" =~ ^[0-9]+$ ]] && [ "$core_choice" -gt 0 ]; then
MESON_NUM_CORES="$core_choice"
log "${BLUE}[Config] Set number of cores to: ${MESON_NUM_CORES}${NC}"
elif [ -n "$core_choice" ]; then
dialog --msgbox "Invalid input. Please enter a positive number." 6 40
fi
;;
esac
}
run_main_tui() {
if ! check_dialog_installed; then return 1; fi
while true; do
local build_dir_status="Not Found"
[ -d "$BUILD_DIR" ] && build_dir_status="Found"
local choice
choice=$(dialog --clear --backtitle "GridFire Installation and Build Manager" \
--title "Main Menu" \
--menu "DIR: ${BUILD_DIR} | TYPE: ${MESON_BUILD_TYPE} | CORES: ${MESON_NUM_CORES}\nPREFIX: ${INSTALL_PREFIX}\nLOG: ${MESON_LOG_LEVEL} | PKG-CONFIG: ${MESON_PKG_CONFIG}" 20 70 10 \
"1" "Install System Dependencies" \
"2" "Configure Build Options" \
"3" "Install Python Bindings" \
"4" "Run Full Build (Setup + Compile)" \
"5" "Run Meson Setup/Reconfigure" \
"6" "Run Meson Compile" \
"7" "Run Meson Install (requires sudo)" \
"8" "Run Tests" \
"9" "Exit" \
3>&1 1>&2 2>&3)
clear
case "$choice" in
1) run_dependency_installer_tui ;;
2) run_build_config_tui ;;
3) run_python_bindings_tui ;;
4) run_meson_setup && run_meson_compile ;;
5) run_meson_setup ;;
6) run_meson_compile ;;
7) run_meson_install ;;
8) run_meson_tests ;;
9) break ;;
*) log "${YELLOW}[Info] TUI cancelled.${NC}"; break ;;
esac
done
clear
}
# --- Script Entry Point ---
main() {
if [[ " $@ " =~ " --help " ]] || [[ " $@ " =~ " -h " ]]; then show_help; exit 0; fi
if [[ " $@ " =~ " --clean " ]]; then log "${BLUE}[Info] Cleaning up...${NC}"; rm -rf "$BUILD_DIR" "$LOGFILE"; fi
echo "" > "$LOGFILE" # Clear log file
log "--- GridFire Installation Log ---"
log "Date: $(date)"
log "OS: ${OS_NAME}, Distro: ${DISTRO_ID}"
if [[ " $@ " =~ " --tui " ]]; then
run_main_tui
log "${GREEN}Exited TUI mode.${NC}"
exit 0 exit 0
fi fi
log "\n${YELLOW}--- Some dependencies are missing ---${NC}" # --- Non-TUI path ---
log "\n${BLUE}--- Checking System Dependencies (CLI Mode) ---${NC}"
if [[ " $@ " =~ " --tui " ]]; then declare -A CHECKS=(
run_tui [compiler]="check_compiler" [python-dev]="check_python_dev"
else [cmake]="check_cmake" [meson]="check_meson" [boost]="check_boost"
# Interactive command-line prompts )
for dep in "${!DEP_STATUS[@]}"; do local all_deps_met=true
if [ "${DEP_STATUS[$dep]}" -ne 0 ]; then for dep in "${!CHECKS[@]}"; do
local install_cmd if ! ${CHECKS[$dep]}; then
install_cmd=$(get_install_cmd "$dep") all_deps_met=false
if [ -n "$install_cmd" ]; then local install_cmd; install_cmd=$(get_install_cmd "$dep")
if prompt_yes_no "Dependency '${dep}' is missing. Attempt to install it now? (y/n):"; then if [ -n "$install_cmd" ]; then
run_install_cmd "$install_cmd" if prompt_yes_no "Dependency '${dep}' is missing. Attempt to install? (y/n):"; then
run_install_cmd "$install_cmd"
fi
else
log "${RED}[Error] No automatic installation for '${dep}'. Please install manually.${NC}"
fi fi
else
log "${RED}[Error] No automatic installation command available for '${dep}' on your system. Please install it manually.${NC}"
fi
fi fi
done
fi
# Final check before build
log "\n${BLUE}--- Re-checking dependencies after installation attempts ---${NC}"
check_compiler; DEP_STATUS[compiler]=$?
check_python_dev; DEP_STATUS[python-dev]=$?
check_cmake; DEP_STATUS[cmake]=$?
check_meson; DEP_STATUS[meson]=$?
check_boost; DEP_STATUS[boost]=$?
all_deps_met=0
local failed_deps=""
for dep in "${!DEP_STATUS[@]}"; do
if [ "${DEP_STATUS[$dep]}" -ne 0 ]; then
all_deps_met=1
failed_deps+="${dep} "
fi
done done
if [ $all_deps_met -eq 0 ]; then log "\n${BLUE}--- Re-checking all dependencies ---${NC}"
log "\n${GREEN}--- All dependencies are now met! ---${NC}" local final_fail=false
run_meson_build for dep in "${!CHECKS[@]}"; do
else if ! ${CHECKS[$dep]}; then
log "\n${RED}[FATAL] The following dependencies are still missing: ${failed_deps}${NC}" log "${RED}[FATAL] Dependency still missing: ${dep}${NC}"
log "${RED}Please install them manually and re-run this script.${NC}" final_fail=true
log "${RED}Check ${LOGFILE} for detailed error messages.${NC}" fi
exit 1 done
if $final_fail; then
log "${RED}Please install missing dependencies and re-run.${NC}"
exit 1
fi fi
log "\n${GREEN}--- All dependencies met. Proceeding with build. ---${NC}"
run_meson_setup && run_meson_compile
} }
# Run the main function
main "$@" main "$@"