build(check): added check removed install
added check.sh to check dependencies
This commit is contained in:
388
check.sh
Executable file
388
check.sh
Executable file
@@ -0,0 +1,388 @@
|
||||
#!/usr/bin/env bash
|
||||
#
|
||||
# install.sh -- GridFire build-dependency checker.
|
||||
#
|
||||
# This script does NOT install anything. It detects your operating system,
|
||||
# checks each build dependency, and prints the exact commands to run if
|
||||
# something is missing or too old. Nothing on your system is modified.
|
||||
#
|
||||
# Dependencies checked:
|
||||
# 1. Meson >= 1.6.0
|
||||
# 2. Ninja (any recent)
|
||||
# 3. CMake >= 3.16
|
||||
# 4. pkg-config (or pkgconf)
|
||||
# 5. A C and C++ toolchain: GCC >= 14 OR Clang >= 17 (either is fine),
|
||||
# with a working C++23 standard library
|
||||
# 6. Fortran (gfortran >= 14) -- only when --fortran is passed
|
||||
#
|
||||
# Supported platforms: Linux (apt / dnf / pacman / zypper) and macOS on
|
||||
# Apple Silicon. macOS x86_64 and Windows are NOT supported.
|
||||
#
|
||||
# Usage:
|
||||
# ./install.sh check core dependencies
|
||||
# ./install.sh --fortran also check for a Fortran compiler
|
||||
# ./install.sh --help show this help
|
||||
|
||||
set -u
|
||||
|
||||
MESON_MIN="1.6.0"
|
||||
CMAKE_MIN="3.16"
|
||||
GCC_MIN="14"
|
||||
CLANG_MIN="17"
|
||||
GFORTRAN_MIN="14"
|
||||
|
||||
if [ -t 1 ]; then
|
||||
RED=$'\033[0;31m'; GREEN=$'\033[0;32m'; YELLOW=$'\033[1;33m'
|
||||
BLUE=$'\033[0;34m'; BOLD=$'\033[1m'; NC=$'\033[0m'
|
||||
else
|
||||
RED=""; GREEN=""; YELLOW=""; BLUE=""; BOLD=""; NC=""
|
||||
fi
|
||||
|
||||
ok() { printf ' %s[ OK ]%s %s\n' "$GREEN" "$NC" "$1"; }
|
||||
bad() { printf ' %s[FAIL]%s %s\n' "$RED" "$NC" "$1"; }
|
||||
warn() { printf ' %s[WARN]%s %s\n' "$YELLOW" "$NC" "$1"; }
|
||||
info() { printf ' %s[INFO]%s %s\n' "$BLUE" "$NC" "$1"; }
|
||||
hdr() { printf '\n%s%s%s\n' "$BOLD" "$1" "$NC"; }
|
||||
|
||||
FIX_NOTES=""
|
||||
FAIL_COUNT=0
|
||||
add_fix() { FIX_NOTES="${FIX_NOTES}$1\n"; }
|
||||
note_fail() { FAIL_COUNT=$((FAIL_COUNT + 1)); }
|
||||
|
||||
WANT_FORTRAN=0
|
||||
for arg in "$@"; do
|
||||
case "$arg" in
|
||||
--fortran) WANT_FORTRAN=1 ;;
|
||||
-h|--help) sed -n '2,/^$/p' "$0" | sed 's/^# \{0,1\}//'; exit 0 ;;
|
||||
*) printf '%sUnknown argument: %s%s\n' "$RED" "$arg" "$NC"; exit 2 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
version_ge() {
|
||||
local a b ai bi n i
|
||||
IFS='.' read -ra a <<< "$1"
|
||||
IFS='.' read -ra b <<< "$2"
|
||||
n=${#a[@]}; [ ${#b[@]} -gt "$n" ] && n=${#b[@]}
|
||||
for ((i=0; i<n; i++)); do
|
||||
ai=${a[i]:-0}; bi=${b[i]:-0}
|
||||
ai=${ai%%[!0-9]*}; bi=${bi%%[!0-9]*}
|
||||
ai=${ai:-0}; bi=${bi:-0}
|
||||
if ((10#$ai > 10#$bi)); then return 0; fi
|
||||
if ((10#$ai < 10#$bi)); then return 1; fi
|
||||
done
|
||||
return 0
|
||||
}
|
||||
|
||||
extract_version() {
|
||||
printf '%s' "$1" | grep -oE '[0-9]+(\.[0-9]+){0,3}' | head -n1
|
||||
}
|
||||
|
||||
OS="$(uname -s)"
|
||||
ARCH="$(uname -m)"
|
||||
PKG_MGR=""
|
||||
DISTRO_NAME=""
|
||||
|
||||
detect_platform() {
|
||||
case "$OS" in
|
||||
Darwin)
|
||||
if [ "$ARCH" != "arm64" ]; then
|
||||
printf '%sUnsupported platform.%s\n' "$RED" "$NC"
|
||||
printf 'GridFire supports macOS on Apple Silicon (arm64) only; detected macOS on %s.\n' "$ARCH"
|
||||
printf 'macOS x86_64 (Intel) is not supported.\n'
|
||||
exit 1
|
||||
fi
|
||||
DISTRO_NAME="macOS (Apple Silicon)"
|
||||
if command -v brew >/dev/null 2>&1; then
|
||||
PKG_MGR="brew"
|
||||
else
|
||||
PKG_MGR="brew-missing"
|
||||
fi
|
||||
;;
|
||||
Linux)
|
||||
if command -v apt-get >/dev/null 2>&1; then PKG_MGR="apt"
|
||||
elif command -v dnf >/dev/null 2>&1; then PKG_MGR="dnf"
|
||||
elif command -v pacman >/dev/null 2>&1; then PKG_MGR="pacman"
|
||||
elif command -v zypper >/dev/null 2>&1; then PKG_MGR="zypper"
|
||||
else PKG_MGR="unknown"; fi
|
||||
if [ -r /etc/os-release ]; then
|
||||
# shellcheck disable=SC1091
|
||||
DISTRO_NAME="$(. /etc/os-release; printf '%s' "${PRETTY_NAME:-Linux}")"
|
||||
else
|
||||
DISTRO_NAME="Linux"
|
||||
fi
|
||||
;;
|
||||
*)
|
||||
printf '%sUnsupported platform: %s.%s\n' "$RED" "$OS" "$NC"
|
||||
printf 'GridFire supports Linux and macOS (Apple Silicon). Windows is not supported.\n'
|
||||
printf 'On Windows, use WSL2 with a supported Linux distribution.\n'
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
pkg_cmd() {
|
||||
case "$PKG_MGR" in
|
||||
apt)
|
||||
case "$1" in
|
||||
ninja) echo "sudo apt install ninja-build" ;;
|
||||
cmake) echo "sudo apt install cmake" ;;
|
||||
pkgconfig) echo "sudo apt install pkg-config" ;;
|
||||
gcc) echo "sudo apt install g++-14 gcc-14" ;;
|
||||
clang) echo "sudo apt install clang-18 libstdc++-14-dev" ;;
|
||||
gfortran) echo "sudo apt install gfortran-14" ;;
|
||||
esac ;;
|
||||
dnf)
|
||||
case "$1" in
|
||||
ninja) echo "sudo dnf install ninja-build" ;;
|
||||
cmake) echo "sudo dnf install cmake" ;;
|
||||
pkgconfig) echo "sudo dnf install pkgconf-pkg-config" ;;
|
||||
gcc) echo "sudo dnf install gcc-c++" ;;
|
||||
clang) echo "sudo dnf install clang" ;;
|
||||
gfortran) echo "sudo dnf install gcc-gfortran" ;;
|
||||
esac ;;
|
||||
pacman)
|
||||
case "$1" in
|
||||
ninja) echo "sudo pacman -S ninja" ;;
|
||||
cmake) echo "sudo pacman -S cmake" ;;
|
||||
pkgconfig) echo "sudo pacman -S pkgconf" ;;
|
||||
gcc) echo "sudo pacman -S gcc" ;;
|
||||
clang) echo "sudo pacman -S clang" ;;
|
||||
gfortran) echo "sudo pacman -S gcc-fortran" ;;
|
||||
esac ;;
|
||||
zypper)
|
||||
case "$1" in
|
||||
ninja) echo "sudo zypper install ninja" ;;
|
||||
cmake) echo "sudo zypper install cmake" ;;
|
||||
pkgconfig) echo "sudo zypper install pkg-config" ;;
|
||||
gcc) echo "sudo zypper install gcc14-c++" ;;
|
||||
clang) echo "sudo zypper install clang" ;;
|
||||
gfortran) echo "sudo zypper install gcc14-fortran" ;;
|
||||
esac ;;
|
||||
brew|brew-missing)
|
||||
case "$1" in
|
||||
ninja) echo "brew install ninja" ;;
|
||||
cmake) echo "brew install cmake" ;;
|
||||
pkgconfig) echo "brew install pkg-config" ;;
|
||||
gcc) echo "brew install gcc" ;;
|
||||
clang) echo "brew install llvm # then use /opt/homebrew/opt/llvm/bin/clang++" ;;
|
||||
gfortran) echo "brew install gcc # provides gfortran" ;;
|
||||
esac ;;
|
||||
*)
|
||||
echo "(install '$1' using your system package manager)" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
check_meson() {
|
||||
if command -v meson >/dev/null 2>&1; then
|
||||
local v; v="$(extract_version "$(meson --version 2>/dev/null)")"
|
||||
if [ -n "$v" ] && version_ge "$v" "$MESON_MIN"; then
|
||||
ok "Meson $v (>= $MESON_MIN)"
|
||||
else
|
||||
bad "Meson ${v:-?} found but GridFire needs >= $MESON_MIN"
|
||||
note_fail
|
||||
add_fix "Meson upgrade (isolated, recommended):\n pipx upgrade meson || pipx install meson\n or with pip:\n python3 -m pip install --user --upgrade meson"
|
||||
fi
|
||||
else
|
||||
bad "Meson not found (need >= $MESON_MIN)"
|
||||
note_fail
|
||||
add_fix "Install Meson (isolated, recommended):\n pipx install meson\n If pipx is unavailable:\n python3 -m pip install --user meson\n (pipx itself: ${PKG_MGR/brew-missing/brew} install pipx; on Linux: python3 -m pip install --user pipx)"
|
||||
fi
|
||||
}
|
||||
|
||||
check_ninja() {
|
||||
if command -v ninja >/dev/null 2>&1; then
|
||||
ok "Ninja $(extract_version "$(ninja --version 2>/dev/null)")"
|
||||
elif command -v samu >/dev/null 2>&1; then
|
||||
ok "samurai (ninja-compatible) found"
|
||||
else
|
||||
bad "Ninja not found"
|
||||
note_fail
|
||||
add_fix "Install Ninja (isolated, recommended):\n pipx inject meson ninja # if meson via pipx\n or:\n python3 -m pip install --user ninja\n or via system packages:\n $(pkg_cmd ninja)"
|
||||
fi
|
||||
}
|
||||
|
||||
check_cmake() {
|
||||
if command -v cmake >/dev/null 2>&1; then
|
||||
local v; v="$(extract_version "$(cmake --version 2>/dev/null)")"
|
||||
if [ -n "$v" ] && version_ge "$v" "$CMAKE_MIN"; then
|
||||
ok "CMake $v (>= $CMAKE_MIN)"
|
||||
else
|
||||
bad "CMake ${v:-?} found but >= $CMAKE_MIN required (SUNDIALS/CppAD subprojects)"
|
||||
note_fail
|
||||
add_fix "Upgrade CMake:\n $(pkg_cmd cmake)\n or isolated: python3 -m pip install --user --upgrade cmake"
|
||||
fi
|
||||
else
|
||||
bad "CMake not found (required to build the SUNDIALS and CppAD subprojects)"
|
||||
note_fail
|
||||
add_fix "Install CMake:\n $(pkg_cmd cmake)\n or isolated: python3 -m pip install --user cmake"
|
||||
fi
|
||||
}
|
||||
|
||||
check_pkgconfig() {
|
||||
if command -v pkg-config >/dev/null 2>&1; then
|
||||
ok "pkg-config $(extract_version "$(pkg-config --version 2>/dev/null)")"
|
||||
elif command -v pkgconf >/dev/null 2>&1; then
|
||||
ok "pkgconf $(extract_version "$(pkgconf --version 2>/dev/null)") (pkg-config compatible)"
|
||||
else
|
||||
bad "pkg-config not found"
|
||||
note_fail
|
||||
add_fix "Install pkg-config:\n $(pkg_cmd pkgconfig)"
|
||||
fi
|
||||
}
|
||||
|
||||
probe_cxx23() {
|
||||
local cxx="$1" dir src out rc
|
||||
command -v "$cxx" >/dev/null 2>&1 || return 2
|
||||
dir="$(mktemp -d 2>/dev/null)" || return 3
|
||||
src="$dir/gf_probe.cpp"
|
||||
out="$dir/gf_probe.out"
|
||||
cat > "$src" <<'EOF'
|
||||
#include <print>
|
||||
#include <format>
|
||||
int main() { std::println("ok {}", 23); }
|
||||
EOF
|
||||
"$cxx" -std=c++23 "$src" -o "$out" >/dev/null 2>&1
|
||||
rc=$?
|
||||
rm -rf "$dir"
|
||||
return $rc
|
||||
}
|
||||
check_toolchain() {
|
||||
local found_ok=0 detail=""
|
||||
|
||||
local candidates=()
|
||||
[ -n "${CXX:-}" ] && candidates+=("$CXX")
|
||||
candidates+=(clang++ clang++-21 clang++-20 clang++-19 clang++-18 clang++-17 g++ g++-16 g++-15 g++-14)
|
||||
if [ "$OS" = "Darwin" ]; then
|
||||
candidates+=(/opt/homebrew/opt/llvm/bin/clang++ /usr/local/opt/llvm/bin/clang++)
|
||||
fi
|
||||
|
||||
local seen="" cxx ver id minreq
|
||||
for cxx in "${candidates[@]}"; do
|
||||
command -v "$cxx" >/dev/null 2>&1 || continue
|
||||
local rp; rp="$(command -v "$cxx")"
|
||||
case " $seen " in *" $rp "*) continue ;; esac
|
||||
seen="$seen $rp"
|
||||
|
||||
ver="$("$cxx" --version 2>/dev/null | head -n1)"
|
||||
if printf '%s' "$ver" | grep -qiE 'clang'; then
|
||||
id="clang"; minreq="$CLANG_MIN"
|
||||
elif printf '%s' "$ver" | grep -qiE 'g\+\+|gcc|free software foundation'; then
|
||||
id="gcc"; minreq="$GCC_MIN"
|
||||
else
|
||||
id="unknown"; minreq=""
|
||||
fi
|
||||
local vnum; vnum="$(extract_version "$ver")"
|
||||
|
||||
if probe_cxx23 "$cxx"; then
|
||||
if [ -n "$minreq" ] && [ -n "$vnum" ] && ! version_ge "$vnum" "$minreq"; then
|
||||
warn "$cxx ($id $vnum): C++23 probe passed but below tested floor ($minreq) -- usable, upgrade if you hit errors"
|
||||
else
|
||||
ok "$cxx ($id ${vnum:-?}): C++23 standard library working"
|
||||
fi
|
||||
found_ok=1
|
||||
[ -z "${WORKING_CXX:-}" ] && WORKING_CXX="$rp"
|
||||
else
|
||||
detail="${detail}\n - $cxx ($id ${vnum:-?}): present but failed the C++23 compile probe"
|
||||
fi
|
||||
done
|
||||
|
||||
local have_cc=0
|
||||
for c in "${CC:-}" cc gcc clang; do
|
||||
[ -n "$c" ] && command -v "$c" >/dev/null 2>&1 && { have_cc=1; break; }
|
||||
done
|
||||
|
||||
if [ "$found_ok" -eq 1 ] && [ "$have_cc" -eq 1 ]; then
|
||||
ok "C toolchain present"
|
||||
[ -n "${WORKING_CXX:-}" ] && info "Suggested: CXX=$WORKING_CXX meson setup build"
|
||||
return
|
||||
fi
|
||||
|
||||
if [ "$found_ok" -ne 1 ]; then
|
||||
bad "No C++ compiler with working C++23 support found (need GCC >= $GCC_MIN or Clang >= $CLANG_MIN)"
|
||||
note_fail
|
||||
[ -n "$detail" ] && printf ' Compilers seen but rejected:%b\n' "$detail"
|
||||
fi
|
||||
if [ "$have_cc" -ne 1 ]; then
|
||||
bad "No C compiler found"
|
||||
note_fail
|
||||
fi
|
||||
|
||||
|
||||
local fix="Install a C/C++ toolchain (Clang >= $CLANG_MIN or GCC >= $GCC_MIN):\n $(pkg_cmd clang)\n or GCC:\n $(pkg_cmd gcc)"
|
||||
# local fix="Install a C/C++ toolchain (GCC >= $GCC_MIN or Clang >= $CLANG_MIN):\n $(pkg_cmd gcc)\n or Clang:\n $(pkg_cmd clang)"
|
||||
if [ "$OS" = "Linux" ]; then
|
||||
fix="$fix\n Note: on Linux, Clang uses the system libstdc++ -- if a new Clang fails the\n C++23 probe, install a newer libstdc++ (e.g. via g++-14) and Clang will use it."
|
||||
elif [ "$OS" = "Darwin" ]; then
|
||||
fix="$fix\n Apple Clang: update Xcode / Command Line Tools to Xcode 16+\n xcode-select --install (or update via the App Store)"
|
||||
fi
|
||||
add_fix "$fix"
|
||||
}
|
||||
|
||||
check_fortran() {
|
||||
[ "$WANT_FORTRAN" -eq 1 ] || return 0
|
||||
if command -v gfortran >/dev/null 2>&1; then
|
||||
local v; v="$(extract_version "$(gfortran --version 2>/dev/null | head -n1)")"
|
||||
if [ -n "$v" ] && version_ge "$v" "$GFORTRAN_MIN"; then
|
||||
ok "gfortran $v (>= $GFORTRAN_MIN)"
|
||||
else
|
||||
bad "gfortran ${v:-?} found but >= $GFORTRAN_MIN required"
|
||||
note_fail
|
||||
add_fix "Upgrade gfortran:\n $(pkg_cmd gfortran)"
|
||||
fi
|
||||
else
|
||||
bad "gfortran not found (required by --fortran / -Dbuild_fortran=true)"
|
||||
note_fail
|
||||
add_fix "Install gfortran:\n $(pkg_cmd gfortran)\n (GridFire only supports gfortran; other Fortran compilers need -Dunsafe_fortran=true)"
|
||||
fi
|
||||
}
|
||||
|
||||
printf '%s======================================================%s\n' "$BOLD" "$NC"
|
||||
printf '%s GridFire build-dependency check%s\n' "$BOLD" "$NC"
|
||||
printf '%s======================================================%s\n' "$BOLD" "$NC"
|
||||
|
||||
detect_platform
|
||||
info "Platform: $DISTRO_NAME ($ARCH)"
|
||||
case "$PKG_MGR" in
|
||||
brew-missing)
|
||||
warn "Homebrew not found. Install it first: https://brew.sh"
|
||||
warn "All macOS remediation commands below assume Homebrew." ;;
|
||||
unknown)
|
||||
warn "Could not identify a supported package manager (apt/dnf/pacman/zypper)." ;;
|
||||
*) info "Package manager: $PKG_MGR" ;;
|
||||
esac
|
||||
|
||||
hdr "Build tools"
|
||||
check_meson
|
||||
check_ninja
|
||||
check_cmake
|
||||
check_pkgconfig
|
||||
|
||||
hdr "Compiler toolchain"
|
||||
check_toolchain
|
||||
|
||||
if [ "$WANT_FORTRAN" -eq 1 ]; then
|
||||
hdr "Fortran (requested via --fortran)"
|
||||
check_fortran
|
||||
fi
|
||||
|
||||
printf '\n%s======================================================%s\n' "$BOLD" "$NC"
|
||||
if [ "$FAIL_COUNT" -eq 0 ]; then
|
||||
printf '%s All dependencies satisfied.%s\n' "$GREEN" "$NC"
|
||||
printf '%s======================================================%s\n' "$BOLD" "$NC"
|
||||
printf '\nYou can build GridFire with:\n\n'
|
||||
if [ -n "${WORKING_CXX:-}" ]; then
|
||||
printf ' CXX=%s meson setup build\n' "$WORKING_CXX"
|
||||
else
|
||||
printf ' meson setup build\n'
|
||||
fi
|
||||
printf ' meson compile -C build\n'
|
||||
printf ' sudo meson install -C build\n\n'
|
||||
exit 0
|
||||
else
|
||||
printf '%s %d dependency problem(s) found -- see below.%s\n' "$RED" "$FAIL_COUNT" "$NC"
|
||||
printf '%s======================================================%s\n' "$BOLD" "$NC"
|
||||
printf '\n%sThis script does not install anything. Run the commands below yourself:%s\n\n' "$BOLD" "$NC"
|
||||
printf '%b\n' "$FIX_NOTES"
|
||||
printf 'Re-run %s./install.sh%s after installing to confirm.\n\n' "$BOLD" "$NC"
|
||||
exit 1
|
||||
fi
|
||||
@@ -1,3 +0,0 @@
|
||||
#!/bin/bash
|
||||
|
||||
./install.sh --tui
|
||||
1378
install.sh
1378
install.sh
File diff suppressed because it is too large
Load Diff
@@ -1,8 +0,0 @@
|
||||
The logical flow of using this installer is (for C++ usage): install system dependencies > "Run Full Build" > "Run Meson Install"
|
||||
The logical flow of using this installer is (for Python usage): install system dependencies > "Install Python Bindings" (note this will take a while).
|
||||
When building in release mode (default), static analysis of CppAD throws a few bounds warnings. Testing indicates that these are not problems. These warnings do not get identified in debug builds.
|
||||
GridFire requires gcc >= 13.0.0 or clang >= 16.0.0
|
||||
A directory named meson-boost-test will be created in the build directory. This is used to test the boost installation and may be deleted after the build is complete.
|
||||
GridFire requires a version of boost compatible with C++23. Certain versions of Ubuntu prior released prior to 24.04 do not have a compatible version of boost in their repositories. In this case, you will need to install boost from source.
|
||||
GridFire is authored by the 4D-STAR collaboration and Emily M. Boudreaux.
|
||||
4D-STAR is funded by European Research Council (ERC) under the Horizon Europe programme (Synergy Grant agreement No. 101071505: 4D-STAR). Work for this project is funded by the European Union. Views and opinions expressed are however those of the author(s) only and do not necessarily reflect those of the European Union or the European Research Council.
|
||||
Reference in New Issue
Block a user