#!/usr/bin/env bash # detect-platforms — probe available platform bridge dependencies # # Reports which el-native platform bridges can be built on this machine, # with install instructions for anything that is missing. # # Usage: ./detect-platforms # ./build.sh platforms (from native-hello) set -uo pipefail SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # ── Helpers ─────────────────────────────────────────────────────────────────── PASS="[+]" FAIL="[ ]" _ok() { printf " ${PASS} %-22s %s\n" "$1" "$2"; } _miss() { printf " ${FAIL} %-22s %s\n" "$1" "$2"; } # ── Header ──────────────────────────────────────────────────────────────────── echo "" echo "==> el-native platform detection" echo "" echo " Checking build dependencies for each platform bridge..." echo "" AVAILABLE=0 MISSING=0 # ── macOS / AppKit ──────────────────────────────────────────────────────────── if [[ "$(uname)" == "Darwin" ]]; then if xcrun --find clang &>/dev/null && xcrun --find xcodebuild &>/dev/null 2>/dev/null || \ xcrun --find cc &>/dev/null; then CLT_INFO="Xcode CLT $(xcode-select -p 2>/dev/null | sed 's|/Developer||' || echo '')" _ok "macOS/AppKit" "-DEL_TARGET_MACOS ${CLT_INFO}" AVAILABLE=$((AVAILABLE + 1)) else _miss "macOS/AppKit" "-DEL_TARGET_MACOS (Xcode CLT missing — xcode-select --install)" MISSING=$((MISSING + 1)) fi else _miss "macOS/AppKit" "-DEL_TARGET_MACOS (not on macOS)" fi # ── iOS / UIKit ─────────────────────────────────────────────────────────────── if [[ "$(uname)" == "Darwin" ]]; then if xcrun --sdk iphoneos --show-sdk-path &>/dev/null 2>&1; then SDK_VER=$(xcrun --sdk iphoneos --show-sdk-version 2>/dev/null || echo "") _ok "iOS/UIKit" "-DEL_TARGET_IOS SDK ${SDK_VER} (requires Xcode.app)" AVAILABLE=$((AVAILABLE + 1)) else _miss "iOS/UIKit" "-DEL_TARGET_IOS (iOS SDK not found — install Xcode.app)" MISSING=$((MISSING + 1)) fi else _miss "iOS/UIKit" "-DEL_TARGET_IOS (not on macOS — requires Xcode)" fi # ── Linux / GTK4 ────────────────────────────────────────────────────────────── if pkg-config --exists gtk4 2>/dev/null; then GTK_VER=$(pkg-config --modversion gtk4 2>/dev/null) _ok "Linux/GTK4" "-DEL_TARGET_LINUX gtk4 ${GTK_VER}" AVAILABLE=$((AVAILABLE + 1)) else _miss "Linux/GTK4" "-DEL_TARGET_LINUX (gtk4 not found)" echo " Install: apt install libgtk-4-dev" echo " or: dnf install gtk4-devel" echo " or: brew install gtk4" MISSING=$((MISSING + 1)) fi # ── SDL2 / Embedded Linux / Pi ──────────────────────────────────────────────── SDL2_OK=0 if pkg-config --exists sdl2 2>/dev/null; then SDL2_VER=$(pkg-config --modversion sdl2 2>/dev/null) # Also check for SDL2_ttf (needed for text rendering) if pkg-config --exists SDL2_ttf 2>/dev/null; then TTF_VER=$(pkg-config --modversion SDL2_ttf 2>/dev/null) _ok "SDL2/Embedded" "-DEL_TARGET_SDL2 sdl2 ${SDL2_VER}, SDL2_ttf ${TTF_VER}" else _ok "SDL2/Embedded" "-DEL_TARGET_SDL2 sdl2 ${SDL2_VER} (SDL2_ttf missing — needed for text)" echo " Install: apt install libsdl2-ttf-dev" fi SDL2_OK=1 AVAILABLE=$((AVAILABLE + 1)) elif command -v sdl2-config &>/dev/null; then SDL2_VER=$(sdl2-config --version 2>/dev/null || echo "") _ok "SDL2/Embedded" "-DEL_TARGET_SDL2 sdl2 ${SDL2_VER} (via sdl2-config)" SDL2_OK=1 AVAILABLE=$((AVAILABLE + 1)) fi if [[ $SDL2_OK -eq 0 ]]; then _miss "SDL2/Embedded" "-DEL_TARGET_SDL2 (sdl2 not found)" echo " Install: apt install libsdl2-dev libsdl2-ttf-dev libsdl2-image-dev" echo " or: brew install sdl2 sdl2_ttf sdl2_image" MISSING=$((MISSING + 1)) fi # ── LVGL / Microcontrollers ─────────────────────────────────────────────────── LVGL_OK=0 LVGL_WHERE="" if [ -f "${SCRIPT_DIR}/lvgl/lvgl.h" ]; then LVGL_WHERE="./lvgl/lvgl.h" LVGL_OK=1 elif [ -f "${SCRIPT_DIR}/../lvgl/lvgl.h" ]; then LVGL_WHERE="adjacent lvgl/" LVGL_OK=1 elif [ -f "/usr/include/lvgl/lvgl.h" ]; then LVGL_WHERE="/usr/include/lvgl" LVGL_OK=1 elif [ -f "/usr/local/include/lvgl/lvgl.h" ]; then LVGL_WHERE="/usr/local/include/lvgl" LVGL_OK=1 elif pkg-config --exists lvgl 2>/dev/null; then LVGL_WHERE="pkg-config ($(pkg-config --modversion lvgl 2>/dev/null))" LVGL_OK=1 fi if [[ $LVGL_OK -eq 1 ]]; then _ok "LVGL/MCU" "-DEL_TARGET_LVGL ${LVGL_WHERE}" AVAILABLE=$((AVAILABLE + 1)) else _miss "LVGL/MCU" "-DEL_TARGET_LVGL (lvgl.h not found)" echo " Install: git clone https://github.com/lvgl/lvgl" echo " (place lvgl/ next to el-compiler/runtime/)" MISSING=$((MISSING + 1)) fi # ── Android / JNI ───────────────────────────────────────────────────────────── ANDROID_OK=0 ANDROID_WHERE="" if [ -n "${ANDROID_NDK_HOME:-}" ] && [ -d "${ANDROID_NDK_HOME}" ]; then NDK_VER="" if [ -f "${ANDROID_NDK_HOME}/source.properties" ]; then NDK_VER=$(grep "Pkg.Revision" "${ANDROID_NDK_HOME}/source.properties" \ 2>/dev/null | cut -d= -f2 | tr -d ' ' || echo "") fi ANDROID_WHERE="NDK ${NDK_VER:-(version unknown)} at \$ANDROID_NDK_HOME" ANDROID_OK=1 elif command -v ndk-build &>/dev/null; then ANDROID_WHERE="ndk-build in PATH" ANDROID_OK=1 elif [ -n "${ANDROID_HOME:-}" ] && [ -d "${ANDROID_HOME}/ndk" ]; then ANDROID_WHERE="NDK via \$ANDROID_HOME/ndk" ANDROID_OK=1 fi if [[ $ANDROID_OK -eq 1 ]]; then _ok "Android/JNI" "-DEL_TARGET_ANDROID ${ANDROID_WHERE}" AVAILABLE=$((AVAILABLE + 1)) else _miss "Android/JNI" "-DEL_TARGET_ANDROID (ANDROID_NDK_HOME not set)" echo " Install: https://developer.android.com/studio/releases/ndk" echo " Then: export ANDROID_NDK_HOME=/path/to/ndk" MISSING=$((MISSING + 1)) fi # ── Windows / Win32 (cross or native) ───────────────────────────────────────── WIN32_OK=0 WIN32_WHERE="" if [[ "$(uname)" == MINGW* ]] || [[ "$(uname)" == CYGWIN* ]] || \ [[ "$(uname)" == MSYS* ]]; then WIN32_WHERE="native Windows ($(uname))" WIN32_OK=1 elif command -v x86_64-w64-mingw32-gcc &>/dev/null; then MINGW_VER=$(x86_64-w64-mingw32-gcc --version 2>/dev/null | head -1 || echo "") WIN32_WHERE="mingw cross-compiler — ${MINGW_VER}" WIN32_OK=1 elif command -v i686-w64-mingw32-gcc &>/dev/null; then WIN32_WHERE="mingw 32-bit cross-compiler" WIN32_OK=1 fi if [[ $WIN32_OK -eq 1 ]]; then _ok "Windows/Win32" "-DEL_TARGET_WIN32 ${WIN32_WHERE}" AVAILABLE=$((AVAILABLE + 1)) else _miss "Windows/Win32" "-DEL_TARGET_WIN32 (mingw cross-compiler not found)" echo " Install: brew install mingw-w64" echo " or: apt install gcc-mingw-w64" MISSING=$((MISSING + 1)) fi # ── Summary ─────────────────────────────────────────────────────────────────── echo "" echo " ${AVAILABLE} platform(s) available, ${MISSING} unavailable on this machine." echo "" if [[ -x "${SCRIPT_DIR}/new-platform" ]]; then echo " Scaffold a new bridge: ${SCRIPT_DIR}/new-platform " fi echo " Bridge contract: ${SCRIPT_DIR}/PLATFORM_BRIDGE_SPEC.md" echo ""