135 lines
3.6 KiB
Bash
Executable File
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"
|