Wire up ONNX RetinaFace detector and MobileFaceNet embeddings in the CLI and auth pipeline. Add IR camera detection for Windows Hello-style "Integrated I" cameras and greyscale-only format heuristic. Add histogram normalization for underexposed IR frames from low-power emitters. - Add `onnx` feature flag to CLI crate forwarding to daemon - Wire ONNX detector into `detect` command with fallback to simple detector - Fix IR camera detection for Chicony "Integrated I" naming pattern - Add `normalize_if_dark()` for underexposed IR frames in auth pipeline - Load user config from ~/.config/linux-hello/ as fallback - Update systemd service for IR emitter integration and camera access - Add system installation script and ONNX runtime installer - Update .gitignore for local dev artifacts Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
413 lines
11 KiB
Bash
Executable File
413 lines
11 KiB
Bash
Executable File
#!/bin/bash
|
|
#
|
|
# ONNX Runtime Installer for Linux Hello
|
|
#
|
|
# This script detects the system's glibc version and installs the appropriate
|
|
# ONNX Runtime library for the onnx feature to work.
|
|
#
|
|
# Usage:
|
|
# ./scripts/install-onnx-runtime.sh [--prefix=/usr/local]
|
|
#
|
|
# Options:
|
|
# --prefix=PATH Installation prefix (default: /usr/local)
|
|
# --user Install to ~/.local instead of system-wide
|
|
# --help Show this help message
|
|
#
|
|
|
|
set -e
|
|
|
|
# Colors for output
|
|
RED='\033[0;31m'
|
|
GREEN='\033[0;32m'
|
|
YELLOW='\033[1;33m'
|
|
BLUE='\033[0;34m'
|
|
NC='\033[0m' # No Color
|
|
|
|
# Default values
|
|
PREFIX="/usr/local"
|
|
USER_INSTALL=false
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
PROJECT_DIR="$(dirname "$SCRIPT_DIR")"
|
|
|
|
# ONNX Runtime versions and requirements
|
|
# ort 2.0.0-rc.11 requires ONNX Runtime >= 1.23.x
|
|
ORT_VERSION_REQUIRED="1.23.0"
|
|
ORT_VERSION_LATEST="1.23.0"
|
|
|
|
# glibc requirements
|
|
# - ONNX Runtime 1.23.x bundled in ort: requires glibc >= 2.38
|
|
# - ONNX Runtime 1.23.x standalone: requires glibc >= 2.28
|
|
GLIBC_BUNDLED_MIN="2.38"
|
|
GLIBC_STANDALONE_MIN="2.28"
|
|
|
|
print_header() {
|
|
echo -e "${BLUE}============================================${NC}"
|
|
echo -e "${BLUE} Linux Hello - ONNX Runtime Installer${NC}"
|
|
echo -e "${BLUE}============================================${NC}"
|
|
echo
|
|
}
|
|
|
|
print_success() {
|
|
echo -e "${GREEN}[OK]${NC} $1"
|
|
}
|
|
|
|
print_warning() {
|
|
echo -e "${YELLOW}[WARNING]${NC} $1"
|
|
}
|
|
|
|
print_error() {
|
|
echo -e "${RED}[ERROR]${NC} $1"
|
|
}
|
|
|
|
print_info() {
|
|
echo -e "${BLUE}[INFO]${NC} $1"
|
|
}
|
|
|
|
show_help() {
|
|
cat << EOF
|
|
ONNX Runtime Installer for Linux Hello
|
|
|
|
This script detects your system's glibc version and installs the appropriate
|
|
ONNX Runtime library to enable face detection with ONNX models.
|
|
|
|
USAGE:
|
|
$0 [OPTIONS]
|
|
|
|
OPTIONS:
|
|
--prefix=PATH Installation prefix (default: /usr/local)
|
|
Libraries go to PREFIX/lib/linux-hello/
|
|
--user Install to ~/.local (no sudo required)
|
|
--check Only check compatibility, don't install
|
|
--help Show this help message
|
|
|
|
EXAMPLES:
|
|
# System-wide installation (requires sudo)
|
|
sudo $0
|
|
|
|
# User installation (no sudo)
|
|
$0 --user
|
|
|
|
# Custom prefix
|
|
sudo $0 --prefix=/opt/linux-hello
|
|
|
|
SUPPORTED SYSTEMS:
|
|
- Ubuntu 22.04+ (glibc 2.35+)
|
|
- Debian 12+ (glibc 2.36+)
|
|
- Fedora 37+ (glibc 2.36+)
|
|
- Any Linux with glibc >= 2.28
|
|
|
|
EOF
|
|
}
|
|
|
|
# Get glibc version
|
|
get_glibc_version() {
|
|
local version
|
|
version=$(ldd --version 2>&1 | head -1 | grep -oP '\d+\.\d+' | head -1)
|
|
echo "$version"
|
|
}
|
|
|
|
# Compare version strings (returns 0 if $1 >= $2)
|
|
version_gte() {
|
|
local v1="$1"
|
|
local v2="$2"
|
|
|
|
# Use sort -V for version comparison
|
|
local lowest
|
|
lowest=$(printf '%s\n%s' "$v1" "$v2" | sort -V | head -1)
|
|
|
|
[[ "$lowest" == "$v2" ]]
|
|
}
|
|
|
|
# Detect system architecture
|
|
get_arch() {
|
|
local arch
|
|
arch=$(uname -m)
|
|
case "$arch" in
|
|
x86_64)
|
|
echo "x64"
|
|
;;
|
|
aarch64)
|
|
echo "aarch64"
|
|
;;
|
|
*)
|
|
echo ""
|
|
;;
|
|
esac
|
|
}
|
|
|
|
# Download ONNX Runtime
|
|
download_onnx_runtime() {
|
|
local version="$1"
|
|
local arch="$2"
|
|
local dest_dir="$3"
|
|
|
|
local filename="onnxruntime-linux-${arch}-${version}.tgz"
|
|
local url="https://github.com/microsoft/onnxruntime/releases/download/v${version}/${filename}"
|
|
local temp_dir
|
|
temp_dir=$(mktemp -d)
|
|
|
|
print_info "Downloading ONNX Runtime ${version} for ${arch}..."
|
|
|
|
if command -v wget &> /dev/null; then
|
|
wget -q --show-progress -O "${temp_dir}/${filename}" "$url" || {
|
|
print_error "Failed to download ONNX Runtime"
|
|
rm -rf "$temp_dir"
|
|
return 1
|
|
}
|
|
elif command -v curl &> /dev/null; then
|
|
curl -L --progress-bar -o "${temp_dir}/${filename}" "$url" || {
|
|
print_error "Failed to download ONNX Runtime"
|
|
rm -rf "$temp_dir"
|
|
return 1
|
|
}
|
|
else
|
|
print_error "Neither wget nor curl found. Please install one of them."
|
|
rm -rf "$temp_dir"
|
|
return 1
|
|
fi
|
|
|
|
print_info "Extracting..."
|
|
tar -xzf "${temp_dir}/${filename}" -C "$temp_dir"
|
|
|
|
# Create destination directory
|
|
mkdir -p "$dest_dir"
|
|
|
|
# Copy library files
|
|
local extract_dir="${temp_dir}/onnxruntime-linux-${arch}-${version}"
|
|
cp -r "${extract_dir}/lib/"* "$dest_dir/"
|
|
|
|
# Cleanup
|
|
rm -rf "$temp_dir"
|
|
|
|
print_success "ONNX Runtime ${version} installed to ${dest_dir}"
|
|
return 0
|
|
}
|
|
|
|
# Create environment setup script
|
|
create_env_script() {
|
|
local lib_dir="$1"
|
|
local env_script="$2"
|
|
|
|
cat > "$env_script" << EOF
|
|
# Linux Hello ONNX Runtime Environment
|
|
# Source this file or add to your shell profile:
|
|
# source $env_script
|
|
|
|
export ORT_DYLIB_PATH="${lib_dir}/libonnxruntime.so"
|
|
|
|
# Alternatively, add the library to LD_LIBRARY_PATH:
|
|
# export LD_LIBRARY_PATH="${lib_dir}:\$LD_LIBRARY_PATH"
|
|
EOF
|
|
|
|
chmod +x "$env_script"
|
|
}
|
|
|
|
# Create wrapper scripts
|
|
create_wrapper_scripts() {
|
|
local lib_dir="$1"
|
|
local bin_dir="$2"
|
|
|
|
# Wrapper for linux-hello CLI
|
|
cat > "${bin_dir}/linux-hello-onnx" << EOF
|
|
#!/bin/bash
|
|
# Wrapper script for linux-hello with ONNX support
|
|
export ORT_DYLIB_PATH="${lib_dir}/libonnxruntime.so"
|
|
exec linux-hello "\$@"
|
|
EOF
|
|
chmod +x "${bin_dir}/linux-hello-onnx"
|
|
|
|
# Wrapper for daemon
|
|
cat > "${bin_dir}/linux-hello-daemon-onnx" << EOF
|
|
#!/bin/bash
|
|
# Wrapper script for linux-hello-daemon with ONNX support
|
|
export ORT_DYLIB_PATH="${lib_dir}/libonnxruntime.so"
|
|
exec linux-hello-daemon "\$@"
|
|
EOF
|
|
chmod +x "${bin_dir}/linux-hello-daemon-onnx"
|
|
}
|
|
|
|
# Update systemd service file
|
|
create_systemd_override() {
|
|
local lib_dir="$1"
|
|
local override_dir="/etc/systemd/system/linux-hello.service.d"
|
|
|
|
if [[ $EUID -ne 0 ]]; then
|
|
print_warning "Skipping systemd override (requires root)"
|
|
return 0
|
|
fi
|
|
|
|
mkdir -p "$override_dir"
|
|
|
|
cat > "${override_dir}/onnx-runtime.conf" << EOF
|
|
[Service]
|
|
Environment="ORT_DYLIB_PATH=${lib_dir}/libonnxruntime.so"
|
|
EOF
|
|
|
|
print_success "Created systemd override at ${override_dir}/onnx-runtime.conf"
|
|
print_info "Run 'sudo systemctl daemon-reload' to apply"
|
|
}
|
|
|
|
# Main installation logic
|
|
main() {
|
|
# Parse arguments
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
--prefix=*)
|
|
PREFIX="${1#*=}"
|
|
shift
|
|
;;
|
|
--user)
|
|
USER_INSTALL=true
|
|
PREFIX="$HOME/.local"
|
|
shift
|
|
;;
|
|
--check)
|
|
CHECK_ONLY=true
|
|
shift
|
|
;;
|
|
--help|-h)
|
|
show_help
|
|
exit 0
|
|
;;
|
|
*)
|
|
print_error "Unknown option: $1"
|
|
show_help
|
|
exit 1
|
|
;;
|
|
esac
|
|
done
|
|
|
|
print_header
|
|
|
|
# Detect system
|
|
local glibc_version
|
|
glibc_version=$(get_glibc_version)
|
|
|
|
local arch
|
|
arch=$(get_arch)
|
|
|
|
print_info "Detected system:"
|
|
echo " - glibc version: ${glibc_version}"
|
|
echo " - Architecture: ${arch}"
|
|
echo " - Install prefix: ${PREFIX}"
|
|
echo
|
|
|
|
# Check architecture
|
|
if [[ -z "$arch" ]]; then
|
|
print_error "Unsupported architecture: $(uname -m)"
|
|
print_error "Only x86_64 and aarch64 are supported"
|
|
exit 1
|
|
fi
|
|
|
|
# Check glibc version and determine installation mode
|
|
local install_mode=""
|
|
|
|
if version_gte "$glibc_version" "$GLIBC_BUNDLED_MIN"; then
|
|
print_success "glibc ${glibc_version} >= ${GLIBC_BUNDLED_MIN}"
|
|
print_info "Your system supports the bundled ONNX Runtime"
|
|
print_info "No additional installation needed - just build with:"
|
|
echo
|
|
echo " cargo build --release --features onnx"
|
|
echo
|
|
install_mode="bundled"
|
|
|
|
elif version_gte "$glibc_version" "$GLIBC_STANDALONE_MIN"; then
|
|
print_warning "glibc ${glibc_version} < ${GLIBC_BUNDLED_MIN}"
|
|
print_info "Your system requires the standalone ONNX Runtime"
|
|
install_mode="standalone"
|
|
|
|
else
|
|
print_error "glibc ${glibc_version} < ${GLIBC_STANDALONE_MIN}"
|
|
print_error "Your system is too old for ONNX Runtime"
|
|
print_error "Minimum required: glibc ${GLIBC_STANDALONE_MIN}"
|
|
print_error ""
|
|
print_error "Options:"
|
|
print_error " 1. Upgrade to Ubuntu 22.04+ or equivalent"
|
|
print_error " 2. Build without ONNX: cargo build --release"
|
|
exit 1
|
|
fi
|
|
|
|
# If check only, exit here
|
|
if [[ "$CHECK_ONLY" == "true" ]]; then
|
|
exit 0
|
|
fi
|
|
|
|
# If bundled mode is supported, offer choice
|
|
if [[ "$install_mode" == "bundled" ]]; then
|
|
echo "Do you still want to install standalone ONNX Runtime? (y/N)"
|
|
read -r response
|
|
if [[ ! "$response" =~ ^[Yy]$ ]]; then
|
|
print_info "Exiting. Build with: cargo build --release --features onnx"
|
|
exit 0
|
|
fi
|
|
fi
|
|
|
|
# Check for sudo if system-wide install
|
|
if [[ "$USER_INSTALL" != "true" ]] && [[ $EUID -ne 0 ]]; then
|
|
print_error "System-wide installation requires root privileges"
|
|
print_info "Either run with sudo or use --user for user installation"
|
|
exit 1
|
|
fi
|
|
|
|
# Set up directories
|
|
local lib_dir="${PREFIX}/lib/linux-hello"
|
|
local bin_dir="${PREFIX}/bin"
|
|
local etc_dir="${PREFIX}/etc/linux-hello"
|
|
|
|
print_info "Installing to:"
|
|
echo " - Libraries: ${lib_dir}"
|
|
echo " - Scripts: ${bin_dir}"
|
|
echo " - Config: ${etc_dir}"
|
|
echo
|
|
|
|
# Download and install ONNX Runtime
|
|
download_onnx_runtime "$ORT_VERSION_LATEST" "$arch" "$lib_dir" || exit 1
|
|
|
|
# Create directories
|
|
mkdir -p "$bin_dir" "$etc_dir"
|
|
|
|
# Create environment script
|
|
create_env_script "$lib_dir" "${etc_dir}/onnx-env.sh"
|
|
print_success "Created environment script: ${etc_dir}/onnx-env.sh"
|
|
|
|
# Create wrapper scripts
|
|
create_wrapper_scripts "$lib_dir" "$bin_dir"
|
|
print_success "Created wrapper scripts in ${bin_dir}"
|
|
|
|
# Create systemd override (system-wide only)
|
|
if [[ "$USER_INSTALL" != "true" ]]; then
|
|
create_systemd_override "$lib_dir"
|
|
fi
|
|
|
|
echo
|
|
print_success "Installation complete!"
|
|
echo
|
|
echo "=========================================="
|
|
echo " Next Steps"
|
|
echo "=========================================="
|
|
echo
|
|
echo "1. Build Linux Hello with ONNX support:"
|
|
echo " cargo build --release --features onnx"
|
|
echo
|
|
echo "2. To use ONNX features, either:"
|
|
echo
|
|
echo " a) Source the environment file:"
|
|
echo " source ${etc_dir}/onnx-env.sh"
|
|
echo " ./target/release/linux-hello detect"
|
|
echo
|
|
echo " b) Use the wrapper scripts:"
|
|
echo " ${bin_dir}/linux-hello-onnx detect"
|
|
echo
|
|
echo " c) Set the variable directly:"
|
|
echo " export ORT_DYLIB_PATH=${lib_dir}/libonnxruntime.so"
|
|
echo
|
|
if [[ "$USER_INSTALL" != "true" ]]; then
|
|
echo "3. For the systemd service, reload the daemon:"
|
|
echo " sudo systemctl daemon-reload"
|
|
echo
|
|
fi
|
|
echo "=========================================="
|
|
}
|
|
|
|
main "$@"
|