Files

135 lines
3.6 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
ROOT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
cd "$ROOT_DIR"
WITH_WHISPER="${WITH_WHISPER:-1}"
WHISPER_CUDA="${WHISPER_CUDA:-0}"
JOBS="${JOBS:-$(nproc)}"
WHISPER_DIR="./vendor/whisper.cpp"
MODEL_PATH="./models/ggml-base.en.bin"
need_cmd() {
if ! command -v "$1" >/dev/null 2>&1; then
echo "[build] error: required command '$1' not found" >&2
exit 2
fi
}
have_cmd() {
command -v "$1" >/dev/null 2>&1
}
CFLAGS_COMMON=(
-std=c99 -Wall -Wextra -Wpedantic -O2 -g
-D_POSIX_C_SOURCE=200809L
)
LDFLAGS_COMMON=(
-lpulse-simple -lpulse -lX11 -lXtst -lpthread
)
echo "[build] root: $ROOT_DIR"
echo "[build] WITH_WHISPER=$WITH_WHISPER WHISPER_CUDA=$WHISPER_CUDA JOBS=$JOBS"
need_cmd gcc
need_cmd pkg-config
if ! pkg-config --exists gtk+-3.0; then
echo "[build] error: gtk+-3.0 dev files not found" >&2
exit 2
fi
GTK_CFLAGS_STR="$(pkg-config --cflags gtk+-3.0 2>/dev/null || true)"
if [[ -z "$GTK_CFLAGS_STR" ]]; then
echo "[build] error: gtk+-3.0 cflags are unavailable" >&2
exit 2
fi
if ! printf '#include <gtk/gtk.h>\n' | gcc -x c -fsyntax-only $GTK_CFLAGS_STR - >/dev/null 2>&1; then
echo "[build] error: gtk headers are not usable (gtk/gtk.h check failed)" >&2
exit 2
fi
if [[ "$WITH_WHISPER" == "1" ]]; then
if ! have_cmd cmake; then
echo "[build] warning: cmake not found; forcing WITH_WHISPER=0" >&2
WITH_WHISPER=0
fi
fi
if [[ "$WITH_WHISPER" == "1" ]]; then
if [[ ! -d "$WHISPER_DIR" ]] && ! have_cmd git; then
echo "[build] warning: git not found and whisper.cpp is missing; forcing WITH_WHISPER=0" >&2
WITH_WHISPER=0
fi
fi
if [[ "$WITH_WHISPER" == "1" ]]; then
if [[ ! -f "$MODEL_PATH" ]] && ! have_cmd wget; then
echo "[build] warning: wget not found and model is missing; forcing WITH_WHISPER=0" >&2
WITH_WHISPER=0
fi
fi
echo "[build] effective: WITH_WHISPER=$WITH_WHISPER"
if [[ "$WITH_WHISPER" == "1" ]]; then
if [[ ! -d "$WHISPER_DIR" ]]; then
echo "[build] cloning whisper.cpp..."
mkdir -p ./vendor
git clone https://github.com/ggerganov/whisper.cpp.git "$WHISPER_DIR"
fi
echo "[build] configuring whisper.cpp..."
if [[ "$WHISPER_CUDA" == "1" ]]; then
cmake -S "$WHISPER_DIR" -B "$WHISPER_DIR/build" -DGGML_CUDA=ON
else
cmake -S "$WHISPER_DIR" -B "$WHISPER_DIR/build"
fi
echo "[build] building whisper.cpp..."
cmake --build "$WHISPER_DIR/build" -j"$JOBS"
mkdir -p ./models
if [[ -x ./scripts/download_models.sh ]]; then
echo "[build] ensuring whisper models are downloaded..."
bash ./scripts/download_models.sh
elif [[ ! -f "$MODEL_PATH" ]]; then
echo "[build] downloading model $MODEL_PATH..."
wget -O "$MODEL_PATH" \
https://huggingface.co/ggerganov/whisper.cpp/resolve/main/ggml-base.en.bin
fi
fi
echo "[build] building GTK3 app binary..."
read -r -a GTK_CFLAGS <<< "$(pkg-config --cflags gtk+-3.0)"
read -r -a GTK_LIBS <<< "$(pkg-config --libs gtk+-3.0)"
APP_CFLAGS=("${CFLAGS_COMMON[@]}" "${GTK_CFLAGS[@]}")
APP_LDFLAGS=("${LDFLAGS_COMMON[@]}" "${GTK_LIBS[@]}")
if [[ "$WITH_WHISPER" == "1" ]]; then
APP_CFLAGS+=(
-DWITH_WHISPER=1
-isystem "$WHISPER_DIR/include"
-isystem "$WHISPER_DIR/ggml/include"
)
APP_LDFLAGS+=(
-L"$WHISPER_DIR/build/src"
-L"$WHISPER_DIR/build/ggml/src"
-Wl,-rpath,"$WHISPER_DIR/build/src"
-Wl,-rpath,"$WHISPER_DIR/build/ggml/src"
-lwhisper -lggml
)
fi
gcc "${APP_CFLAGS[@]}" \
./src/gui_main.c ./src/config.c ./src/audio.c ./src/transcribe.c ./src/typer.c ./src/voice_cmd.c \
-o ./voice_linux \
"${APP_LDFLAGS[@]}"
echo "[build] done: ./voice_linux"
echo "[build] run: ./voice_linux"