|
| 1 | +#!/usr/bin/env bash |
| 2 | +set -euo pipefail |
| 3 | + |
| 4 | +# Minimal terminal-only build helper for ViewTouch |
| 5 | +# - Installs missing packages for common Linux distros (apt/dnf/yum/pacman/zypper/apk) |
| 6 | +# - Configures, builds and installs via CMake |
| 7 | +# Usage: ./build.sh [--yes|-y] [--no-deps] [--prefix PATH] [--build-type TYPE] [--jobs N] |
| 8 | + |
| 9 | +PROG="$(basename "$0")" |
| 10 | +TOP_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" |
| 11 | +BUILD_DIR="$TOP_DIR/build" |
| 12 | +PREFIX="/usr/local" |
| 13 | +BUILD_TYPE="RelWithDebInfo" |
| 14 | +JOBS="$(nproc 2>/dev/null || echo 1)" |
| 15 | +AUTO_YES=0 |
| 16 | +INSTALL_DEPS=1 |
| 17 | + |
| 18 | +print_help() { |
| 19 | + cat <<EOF |
| 20 | +Usage: $PROG [options] |
| 21 | +
|
| 22 | +Options: |
| 23 | + --yes, -y Auto-accept installing missing packages |
| 24 | + --no-deps Skip installing system dependencies |
| 25 | + --prefix PATH Install prefix (default: ${PREFIX}) |
| 26 | + --build-type T CMake build type (default: ${BUILD_TYPE}) |
| 27 | + --jobs N Parallel build jobs (default: number of CPU cores) |
| 28 | + -h, --help Show this help |
| 29 | +
|
| 30 | +Examples: |
| 31 | + # Build without installing OS packages |
| 32 | + ./build.sh --no-deps |
| 33 | +
|
| 34 | + # Install deps (prompt) then build and install to /usr |
| 35 | + sudo ./build.sh |
| 36 | +
|
| 37 | + # Auto-install deps, build and install to /usr/local |
| 38 | + ./build.sh --yes |
| 39 | +EOF |
| 40 | +} |
| 41 | + |
| 42 | +while [[ $# -gt 0 ]]; do |
| 43 | + case "$1" in |
| 44 | + --yes|-y) AUTO_YES=1; shift ;; |
| 45 | + --no-deps) INSTALL_DEPS=0; shift ;; |
| 46 | + --prefix) PREFIX="$2"; shift 2 ;; |
| 47 | + --build-type) BUILD_TYPE="$2"; shift 2 ;; |
| 48 | + --jobs) JOBS="$2"; shift 2 ;; |
| 49 | + -h|--help) print_help; exit 0 ;; |
| 50 | + *) echo "Unknown option: $1"; print_help; exit 2 ;; |
| 51 | + esac |
| 52 | +done |
| 53 | + |
| 54 | +# Package lists taken from the repo's cmake/install_dependencies.cmake |
| 55 | +DEB_PACKAGES=(cmake build-essential git libx11-dev libxft-dev libxmu-dev libxpm-dev libxrender-dev libxt-dev libmotif-dev libfreetype6-dev libfontconfig1-dev zlib1g-dev libpng-dev libjpeg-dev libgif-dev pkg-config libxext-dev libxcb1-dev) |
| 56 | +RPM_PACKAGES=(cmake gcc gcc-c++ make git libX11-devel libXft-devel libXmu-devel libXpm-devel libXrender-devel libXt-devel openmotif-devel freetype-devel fontconfig-devel zlib-devel libpng-devel libjpeg-turbo-devel giflib-devel pkgconfig libXext-devel libxcb-devel) |
| 57 | +ARCH_PACKAGES=(cmake base-devel git libx11 libxft libxmu libxpm libxrender libxt openmotif freetype2 fontconfig zlib libpng libjpeg-turbo giflib pkgconf libxext libxcb) |
| 58 | +ZYPPER_PACKAGES=(cmake gcc gcc-c++ make git libX11-devel libXft-devel libXmu-devel libXpm-devel libXrender-devel libXt-devel openmotif-devel freetype2-devel fontconfig-devel zlib-devel libpng16-devel libjpeg-devel libgif-devel pkg-config libXext-devel libxcb-devel) |
| 59 | +APK_PACKAGES=(cmake build-base git libx11-dev libxft-dev libxmu-dev libxpm-dev libxrender-dev libxt-dev openmotif-dev freetype-dev fontconfig-dev zlib-dev libpng-dev libjpeg-turbo-dev giflib-dev pkgconfig libxext-dev libxcb-dev) |
| 60 | + |
| 61 | +# detect package manager and select package list |
| 62 | +PKG_MANAGER="unknown" |
| 63 | +PKGS=() |
| 64 | +if command -v apt-get >/dev/null 2>&1; then |
| 65 | + PKG_MANAGER="apt" |
| 66 | + PKGS=("${DEB_PACKAGES[@]}") |
| 67 | +elif command -v dnf >/dev/null 2>&1; then |
| 68 | + PKG_MANAGER="dnf" |
| 69 | + PKGS=("${RPM_PACKAGES[@]}") |
| 70 | +elif command -v yum >/dev/null 2>&1; then |
| 71 | + PKG_MANAGER="yum" |
| 72 | + PKGS=("${RPM_PACKAGES[@]}") |
| 73 | +elif command -v pacman >/dev/null 2>&1; then |
| 74 | + PKG_MANAGER="pacman" |
| 75 | + PKGS=("${ARCH_PACKAGES[@]}") |
| 76 | +elif command -v zypper >/dev/null 2>&1; then |
| 77 | + PKG_MANAGER="zypper" |
| 78 | + PKGS=("${ZYPPER_PACKAGES[@]}") |
| 79 | +elif command -v apk >/dev/null 2>&1; then |
| 80 | + PKG_MANAGER="apk" |
| 81 | + PKGS=("${APK_PACKAGES[@]}") |
| 82 | +elif command -v brew >/dev/null 2>&1; then |
| 83 | + PKG_MANAGER="brew" |
| 84 | + PKGS=(cmake git pkg-config) |
| 85 | +fi |
| 86 | + |
| 87 | +check_installed() { |
| 88 | + local pkg="$1" |
| 89 | + case "$PKG_MANAGER" in |
| 90 | + apt) |
| 91 | + dpkg -s "$pkg" >/dev/null 2>&1 && return 0 || return 1 |
| 92 | + ;; |
| 93 | + dnf|yum|zypper) |
| 94 | + rpm -q "$pkg" >/dev/null 2>&1 && return 0 || return 1 |
| 95 | + ;; |
| 96 | + pacman) |
| 97 | + pacman -Qi "$pkg" >/dev/null 2>&1 && return 0 || return 1 |
| 98 | + ;; |
| 99 | + apk) |
| 100 | + apk info -e "$pkg" >/dev/null 2>&1 && return 0 || return 1 |
| 101 | + ;; |
| 102 | + brew) |
| 103 | + brew list "$pkg" >/dev/null 2>&1 && return 0 || return 1 |
| 104 | + ;; |
| 105 | + *) |
| 106 | + return 1 |
| 107 | + ;; |
| 108 | + esac |
| 109 | +} |
| 110 | + |
| 111 | +install_missing() { |
| 112 | + local missing=("${@}") |
| 113 | + if [[ ${#missing[@]} -eq 0 ]]; then |
| 114 | + echo "All required packages appear installed." |
| 115 | + return 0 |
| 116 | + fi |
| 117 | + |
| 118 | + echo "Missing packages: ${missing[*]}" |
| 119 | + if [[ $AUTO_YES -ne 1 ]]; then |
| 120 | + read -r -p "Install missing packages? [y/N]: " yn |
| 121 | + [[ $yn =~ ^[Yy]$ ]] || { echo "Skipping package installation."; return 0; } |
| 122 | + fi |
| 123 | + |
| 124 | + case "$PKG_MANAGER" in |
| 125 | + apt) |
| 126 | + sudo apt-get update || true |
| 127 | + if ! sudo apt-get install -y "${missing[@]}"; then |
| 128 | + for p in "${missing[@]}"; do sudo apt-get install -y "$p" || echo "Warning: failed to install $p"; done |
| 129 | + fi |
| 130 | + ;; |
| 131 | + dnf) |
| 132 | + if ! sudo dnf install -y "${missing[@]}"; then |
| 133 | + for p in "${missing[@]}"; do sudo dnf install -y "$p" || echo "Warning: failed to install $p"; done |
| 134 | + fi |
| 135 | + ;; |
| 136 | + yum) |
| 137 | + if ! sudo yum install -y "${missing[@]}"; then |
| 138 | + for p in "${missing[@]}"; do sudo yum install -y "$p" || echo "Warning: failed to install $p"; done |
| 139 | + fi |
| 140 | + ;; |
| 141 | + pacman) |
| 142 | + sudo pacman -Syu --noconfirm || true |
| 143 | + if ! sudo pacman -S --noconfirm "${missing[@]}"; then |
| 144 | + for p in "${missing[@]}"; do sudo pacman -S --noconfirm "$p" || echo "Warning: failed to install $p"; done |
| 145 | + fi |
| 146 | + ;; |
| 147 | + zypper) |
| 148 | + sudo zypper refresh || true |
| 149 | + if ! sudo zypper install -y "${missing[@]}"; then |
| 150 | + for p in "${missing[@]}"; do sudo zypper install -y "$p" || echo "Warning: failed to install $p"; done |
| 151 | + fi |
| 152 | + ;; |
| 153 | + apk) |
| 154 | + if ! sudo apk add --no-cache "${missing[@]}"; then |
| 155 | + for p in "${missing[@]}"; do sudo apk add --no-cache "$p" || echo "Warning: failed to install $p"; done |
| 156 | + fi |
| 157 | + ;; |
| 158 | + brew) |
| 159 | + for p in "${missing[@]}"; do brew install "$p" || echo "Warning: failed to install $p"; done |
| 160 | + ;; |
| 161 | + *) |
| 162 | + echo "Unsupported package manager: $PKG_MANAGER" >&2 |
| 163 | + return 1 |
| 164 | + ;; |
| 165 | + esac |
| 166 | +} |
| 167 | + |
| 168 | +if [[ $INSTALL_DEPS -eq 1 ]]; then |
| 169 | + if [[ "$PKG_MANAGER" == "unknown" ]]; then |
| 170 | + echo "Could not detect a supported package manager. Run './check_dependencies.sh' for guidance." >&2 |
| 171 | + else |
| 172 | + echo "Detected package manager: $PKG_MANAGER" |
| 173 | + # collect missing packages |
| 174 | + missing_list=() |
| 175 | + for pkg in "${PKGS[@]}"; do |
| 176 | + if ! check_installed "$pkg"; then |
| 177 | + missing_list+=("$pkg") |
| 178 | + fi |
| 179 | + done |
| 180 | + install_missing "${missing_list[@]}" |
| 181 | + fi |
| 182 | +fi |
| 183 | + |
| 184 | +# Configure, build, install |
| 185 | +echo "Configuring (build dir: ${BUILD_DIR})" |
| 186 | +cmake -S "$TOP_DIR" -B "$BUILD_DIR" -DCMAKE_BUILD_TYPE="$BUILD_TYPE" -DCMAKE_INSTALL_PREFIX="$PREFIX" |
| 187 | + |
| 188 | +echo "Building (jobs=${JOBS})" |
| 189 | +cmake --build "$BUILD_DIR" --parallel "$JOBS" |
| 190 | + |
| 191 | +echo "Installing to ${PREFIX} (may require sudo)" |
| 192 | +sudo cmake --install "$BUILD_DIR" --prefix "$PREFIX" |
| 193 | + |
| 194 | +echo "Done. If packages failed to install, run './check_dependencies.sh' for manual instructions." |
0 commit comments