voice_audio_multi/scripts/build_linux.sh
Fabio c36510c21e
Some checks failed
Linux Build / Linux cpu (push) Has been cancelled
Linux Build / Linux cpu-clang (push) Has been cancelled
Linux Build / Linux vulkan (push) Has been cancelled
mac-build / macOS CPU (push) Has been cancelled
Nix Build / Nix (cpu) (push) Has been cancelled
Nix Build / Nix (vulkan) (push) Has been cancelled
windows-build / Windows CPU (push) Has been cancelled
Initial import: audio.cpp with Orange Pi documentation
2026-11-04 19:05:22 +01:00

513 lines
16 KiB
Bash
Executable file

#!/usr/bin/env bash
set -euo pipefail
CONDA_ENV=""
BUILD_DIR=""
BUILD_TYPE="RelWithDebInfo"
CUDA_MODE="auto"
CUDA_ARCH=""
VULKAN_MODE="off"
WEBGPU_MODE="off"
HIP_MODE="off"
HIP_VMM=""
GPU_TARGETS=""
USE_CCACHE="OFF"
WITH_TESTS="OFF"
WITH_EXAMPLES="OFF"
WITH_WARMBENCH="OFF"
AUDIOCPP_DEPLOYMENT_BUILD="OFF"
DEPLOYMENT_BUILD_SET="OFF"
AUDIOCPP_BUILD_NATIVE_MODEL_MANAGER="OFF"
AUDIOCPP_USE_SYSTEM_OPENSSL="OFF"
AUDIOCPP_BORINGSSL_ARCHIVE=""
AUDIOCPP_MODEL_SET="full"
AUDIOCPP_MODELS=""
NATIVE_CPU="ON"
LLAMAFILE="ON"
TARGETS=()
JOBS=""
while [[ $# -gt 0 ]]; do
case "$1" in
--conda-env)
CONDA_ENV="$2"
shift 2
;;
--build-dir)
BUILD_DIR="$2"
shift 2
;;
--build-type)
BUILD_TYPE="$2"
shift 2
;;
--backend)
WEBGPU_MODE="off"
if [[ "$2" == "cuda" ]]; then
CUDA_MODE="on"
VULKAN_MODE="off"
HIP_MODE="off"
elif [[ "$2" == "cpu" ]]; then
CUDA_MODE="off"
VULKAN_MODE="off"
HIP_MODE="off"
elif [[ "$2" == "vulkan" ]]; then
CUDA_MODE="off"
VULKAN_MODE="on"
HIP_MODE="off"
elif [[ "$2" == "webgpu" ]]; then
CUDA_MODE="off"
VULKAN_MODE="off"
HIP_MODE="off"
WEBGPU_MODE="on"
elif [[ "$2" == "hip" || "$2" == "rocm" ]]; then
CUDA_MODE="off"
VULKAN_MODE="off"
HIP_MODE="on"
else
echo "Unsupported legacy --backend value: $2" >&2
exit 1
fi
shift 2
;;
--cuda)
CUDA_MODE="$2"
shift 2
;;
--vulkan)
VULKAN_MODE="$2"
shift 2
;;
--webgpu)
WEBGPU_MODE="$2"
shift 2
;;
--hip)
HIP_MODE="$2"
shift 2
;;
--gpu-targets)
GPU_TARGETS="$2"
shift 2
;;
--hip-vmm)
case "$2" in
on|off)
HIP_VMM="$2"
;;
*)
echo "--hip-vmm must be on or off" >&2
exit 1
;;
esac
shift 2
;;
--cuda-arch)
CUDA_ARCH="$2"
shift 2
;;
--ccache)
USE_CCACHE="ON"
shift
;;
--with-tests)
WITH_TESTS="ON"
shift
;;
--with-examples)
WITH_EXAMPLES="ON"
shift
;;
--with-warmbench)
WITH_WARMBENCH="ON"
shift
;;
--deployment-build)
AUDIOCPP_DEPLOYMENT_BUILD="ON"
DEPLOYMENT_BUILD_SET="ON"
shift
;;
--no-deployment-build)
AUDIOCPP_DEPLOYMENT_BUILD="OFF"
DEPLOYMENT_BUILD_SET="ON"
shift
;;
--native-model-manager)
AUDIOCPP_BUILD_NATIVE_MODEL_MANAGER="ON"
shift
;;
--system-openssl)
AUDIOCPP_USE_SYSTEM_OPENSSL="ON"
shift
;;
--boringssl-archive)
AUDIOCPP_BORINGSSL_ARCHIVE="$2"
shift 2
;;
--model-set)
case "$2" in
full|core|custom)
AUDIOCPP_MODEL_SET="$2"
;;
*)
echo "--model-set must be full, core, or custom" >&2
exit 1
;;
esac
shift 2
;;
--models)
AUDIOCPP_MODELS="$2"
shift 2
;;
--native-cpu)
case "$2" in
ON|on|On|1|true|TRUE|yes|YES)
NATIVE_CPU="ON"
;;
OFF|off|Off|0|false|FALSE|no|NO)
NATIVE_CPU="OFF"
;;
*)
echo "--native-cpu must be ON or OFF" >&2
exit 1
;;
esac
shift 2
;;
--llamafile)
case "$2" in
ON|on|On|1|true|TRUE|yes|YES)
LLAMAFILE="ON"
;;
OFF|off|Off|0|false|FALSE|no|NO)
LLAMAFILE="OFF"
;;
*)
echo "--llamafile must be ON or OFF" >&2
exit 1
;;
esac
shift 2
;;
--target)
TARGETS+=("$2")
shift 2
;;
-j|--jobs)
JOBS="$2"
shift 2
;;
*)
echo "Unknown argument: $1" >&2
exit 1
;;
esac
done
if [[ "$AUDIOCPP_BUILD_NATIVE_MODEL_MANAGER" != "ON" ]]; then
if [[ "$AUDIOCPP_USE_SYSTEM_OPENSSL" == "ON" ]]; then
echo "--system-openssl requires --native-model-manager" >&2
exit 1
fi
if [[ -n "$AUDIOCPP_BORINGSSL_ARCHIVE" ]]; then
echo "--boringssl-archive requires --native-model-manager" >&2
exit 1
fi
fi
GENERATOR="Unix Makefiles"
if command -v ninja >/dev/null 2>&1; then
GENERATOR="Ninja"
fi
ENGINE_ENABLE_CUDA="OFF"
ENGINE_ENABLE_VULKAN="OFF"
case "$CUDA_MODE" in
on)
ENGINE_ENABLE_CUDA="ON"
;;
off)
ENGINE_ENABLE_CUDA="OFF"
;;
auto)
if command -v nvcc >/dev/null 2>&1; then
ENGINE_ENABLE_CUDA="ON"
fi
;;
*)
echo "Unknown --cuda mode: $CUDA_MODE (expected on, off, or auto)" >&2
exit 1
;;
esac
case "$VULKAN_MODE" in
on)
ENGINE_ENABLE_VULKAN="ON"
;;
off)
ENGINE_ENABLE_VULKAN="OFF"
;;
*)
echo "Unknown --vulkan mode: $VULKAN_MODE (expected on or off)" >&2
exit 1
;;
esac
case "$WEBGPU_MODE" in
on) ENGINE_ENABLE_WEBGPU="ON" ;;
off) ENGINE_ENABLE_WEBGPU="OFF" ;;
*)
echo "Unknown --webgpu mode: $WEBGPU_MODE (expected on or off)" >&2
exit 1
;;
esac
ENGINE_ENABLE_HIP="OFF"
HIP_CLANG_C=""
HIP_CLANG_CXX=""
case "$HIP_MODE" in
on)
ENGINE_ENABLE_HIP="ON"
# ROCm ships its own clang; hipconfig -l prints the ROCm lib dir's
# parent on some installs, so prefer ROCM_PATH/HIP_PATH when set.
ROCM_HOME="${ROCM_PATH:-${HIP_PATH:-/opt/rocm}}"
HIP_CLANG_C="$ROCM_HOME/bin/clang"
HIP_CLANG_CXX="$ROCM_HOME/bin/clang++"
if [[ ! -x "$HIP_CLANG_CXX" ]] && command -v hipconfig >/dev/null 2>&1; then
HIP_CLANG_C="$(hipconfig -l)/clang"
HIP_CLANG_CXX="$(hipconfig -l)/clang++"
fi
if [[ ! -x "$HIP_CLANG_C" || ! -x "$HIP_CLANG_CXX" ]]; then
echo "ROCm clang not found (looked in $ROCM_HOME/bin and via hipconfig). Install ROCm or set ROCM_PATH." >&2
exit 1
fi
if [[ -z "$GPU_TARGETS" ]]; then
AMDGPU_ARCH=""
if [[ -x "$ROCM_HOME/bin/amdgpu-arch" ]]; then
AMDGPU_ARCH="$ROCM_HOME/bin/amdgpu-arch"
elif command -v amdgpu-arch >/dev/null 2>&1; then
AMDGPU_ARCH="$(command -v amdgpu-arch)"
fi
if [[ -n "$AMDGPU_ARCH" ]]; then
GPU_TARGETS="$("$AMDGPU_ARCH" 2>/dev/null | grep -xE 'gfx[0-9a-f]{3,}' | sort -u | paste -sd ';' -)"
fi
# Fall back to rocminfo (e.g. amdgpu-arch missing from minimal
# ROCm packages, or sandboxed environments where it prints nothing).
# Only accept full agent "Name: gfxXXX" lines — a loose grep would
# also catch fragments like "gfx11" from ISA description text.
if [[ -z "$GPU_TARGETS" ]]; then
ROCMINFO=""
if [[ -x "$ROCM_HOME/bin/rocminfo" ]]; then
ROCMINFO="$ROCM_HOME/bin/rocminfo"
elif command -v rocminfo >/dev/null 2>&1; then
ROCMINFO="$(command -v rocminfo)"
fi
if [[ -n "$ROCMINFO" ]]; then
GPU_TARGETS="$("$ROCMINFO" 2>/dev/null | grep -E '^[[:space:]]+Name:[[:space:]]+gfx[0-9a-f]{3,}[[:space:]]*$' | grep -oE 'gfx[0-9a-f]{3,}' | sort -u | paste -sd ';' -)"
fi
fi
if [[ -z "$GPU_TARGETS" ]]; then
echo "Could not detect GPU targets (tried amdgpu-arch and rocminfo)." >&2
echo "If this machine has no visible AMD GPU (VM/container), pass --gpu-targets gfxXXXX explicitly (semicolon-separated for several)." >&2
exit 1
fi
fi
GPU_TARGETS="${GPU_TARGETS//,/;}"
;;
off)
ENGINE_ENABLE_HIP="OFF"
;;
*)
echo "Unknown --hip mode: $HIP_MODE (expected on or off)" >&2
exit 1
;;
esac
if [[ -n "$HIP_VMM" && "$ENGINE_ENABLE_HIP" != "ON" ]]; then
echo "--hip-vmm can only be used with the HIP backend" >&2
exit 1
fi
# HIP builds default to deployment builds so the produced binaries embed
# package specs and run standalone outside the repo checkout. Other backends
# keep the historical OFF default; --no-deployment-build opts out.
if [[ "$ENGINE_ENABLE_HIP" == "ON" && "$DEPLOYMENT_BUILD_SET" == "OFF" ]]; then
AUDIOCPP_DEPLOYMENT_BUILD="ON"
fi
if [[ "$ENGINE_ENABLE_CUDA" == "ON" && "$ENGINE_ENABLE_VULKAN" == "ON" ]]; then
echo "CUDA and Vulkan backends cannot both be enabled by this script" >&2
exit 1
fi
ENABLED_GPU_BACKENDS=0
[[ "$ENGINE_ENABLE_CUDA" == "ON" ]] && ENABLED_GPU_BACKENDS=$((ENABLED_GPU_BACKENDS + 1))
[[ "$ENGINE_ENABLE_VULKAN" == "ON" ]] && ENABLED_GPU_BACKENDS=$((ENABLED_GPU_BACKENDS + 1))
[[ "$ENGINE_ENABLE_HIP" == "ON" ]] && ENABLED_GPU_BACKENDS=$((ENABLED_GPU_BACKENDS + 1))
[[ "$ENGINE_ENABLE_WEBGPU" == "ON" ]] && ENABLED_GPU_BACKENDS=$((ENABLED_GPU_BACKENDS + 1))
if [[ "$ENABLED_GPU_BACKENDS" -gt 1 ]]; then
echo "CUDA, Vulkan, HIP, and WebGPU backends are mutually exclusive in this script" >&2
exit 1
fi
BACKEND_NAME="cpu"
if [[ "$ENGINE_ENABLE_CUDA" == "ON" ]]; then
BACKEND_NAME="cuda"
elif [[ "$ENGINE_ENABLE_VULKAN" == "ON" ]]; then
BACKEND_NAME="vulkan"
elif [[ "$ENGINE_ENABLE_HIP" == "ON" ]]; then
BACKEND_NAME="hip"
elif [[ "$ENGINE_ENABLE_WEBGPU" == "ON" ]]; then
BACKEND_NAME="webgpu"
fi
BUILD_TYPE_NAME="$(printf '%s' "$BUILD_TYPE" | tr '[:upper:]' '[:lower:]')"
if [[ "$BUILD_TYPE_NAME" == "relwithdebinfo" ]]; then
BUILD_TYPE_NAME="release"
fi
if [[ -z "$BUILD_DIR" ]]; then
BUILD_DIR="build/linux-${BACKEND_NAME}-${BUILD_TYPE_NAME}"
fi
if [[ -z "$JOBS" ]]; then
JOBS="$(nproc 2>/dev/null || echo 8)"
fi
RUNNER=()
if [[ -n "$CONDA_ENV" ]]; then
if ! command -v conda >/dev/null 2>&1; then
echo "conda is required on PATH when --conda-env is used" >&2
exit 1
fi
if ! conda info --envs | awk '{print $1}' | grep -Fxq "$CONDA_ENV"; then
echo "Conda environment '$CONDA_ENV' was not found" >&2
exit 1
fi
RUNNER=(conda run -n "$CONDA_ENV")
fi
if [[ -n "$CONDA_ENV" ]]; then
echo "Using conda env: $CONDA_ENV"
fi
echo "Using generator: $GENERATOR"
echo "Using build dir: $BUILD_DIR"
echo "Including CUDA backend: $ENGINE_ENABLE_CUDA"
if [[ "$ENGINE_ENABLE_CUDA" == "ON" ]]; then
echo "CUDA architectures: ${CUDA_ARCH:-<portable default list>}"
fi
echo "Including Vulkan backend: $ENGINE_ENABLE_VULKAN"
echo "Including HIP backend: $ENGINE_ENABLE_HIP"
echo "Including WebGPU backend: $ENGINE_ENABLE_WEBGPU"
if [[ "$ENGINE_ENABLE_HIP" == "ON" ]]; then
echo "ROCm clang: $HIP_CLANG_CXX"
echo "GPU targets: $GPU_TARGETS"
fi
echo "Native CPU optimization: $NATIVE_CPU"
echo "llamafile SGEMM: $LLAMAFILE"
echo "Building examples: $WITH_EXAMPLES"
echo "Building tests: $WITH_TESTS"
echo "Building warmbench: $WITH_WARMBENCH"
echo "Deployment build: $AUDIOCPP_DEPLOYMENT_BUILD"
echo "Native model manager: $AUDIOCPP_BUILD_NATIVE_MODEL_MANAGER"
if [[ "$AUDIOCPP_BUILD_NATIVE_MODEL_MANAGER" == "ON" ]]; then
echo "System OpenSSL: $AUDIOCPP_USE_SYSTEM_OPENSSL"
echo "BoringSSL archive: ${AUDIOCPP_BORINGSSL_ARCHIVE:-<download at configure time>}"
fi
echo "Model composite: $AUDIOCPP_MODEL_SET"
if [[ -n "$AUDIOCPP_MODELS" ]]; then
echo "Selected models: $AUDIOCPP_MODELS"
fi
CMAKE_ARGS=(
-S .
-B "$BUILD_DIR"
-G "$GENERATOR"
-DCMAKE_BUILD_TYPE="$BUILD_TYPE"
-DENGINE_ENABLE_CUDA="$ENGINE_ENABLE_CUDA"
-DENGINE_ENABLE_VULKAN="$ENGINE_ENABLE_VULKAN"
-DENGINE_ENABLE_HIP="$ENGINE_ENABLE_HIP"
-DENGINE_ENABLE_WEBGPU="$ENGINE_ENABLE_WEBGPU"
-DENGINE_ENABLE_NATIVE_CPU="$NATIVE_CPU"
-DENGINE_ENABLE_LLAMAFILE="$LLAMAFILE"
-DENGINE_BUILD_EXAMPLES="$WITH_EXAMPLES"
-DENGINE_BUILD_TESTS="$WITH_TESTS"
-DENGINE_BUILD_WARMBENCH="$WITH_WARMBENCH"
-DAUDIOCPP_DEPLOYMENT_BUILD="$AUDIOCPP_DEPLOYMENT_BUILD"
-DAUDIOCPP_BUILD_NATIVE_MODEL_MANAGER="$AUDIOCPP_BUILD_NATIVE_MODEL_MANAGER"
-DAUDIOCPP_USE_SYSTEM_OPENSSL="$AUDIOCPP_USE_SYSTEM_OPENSSL"
-UAUDIOCPP_BORINGSSL_ARCHIVE
-DAUDIOCPP_MODEL_SET="$AUDIOCPP_MODEL_SET"
-DAUDIOCPP_MODELS="$AUDIOCPP_MODELS"
)
if [[ -n "$AUDIOCPP_BORINGSSL_ARCHIVE" ]]; then
CMAKE_ARGS+=(-DAUDIOCPP_BORINGSSL_ARCHIVE="$AUDIOCPP_BORINGSSL_ARCHIVE")
fi
# Opt-in: ggml probes for ccache upstream, but audio.cpp's CMakeLists forces that
# probe off, so nothing caches anything unless a launcher is wired up by hand.
# Measured on this tree: ~2% slower on a cold build, ~14x faster on a rebuild.
# Configure prints a hint when ccache is installed and unused; this is the flag
# that hint points at. A launcher already set in the environment is left alone --
# -D wins over both the environment and the existing cache, and this flag means
# "cache the build", not "use ccache rather than whatever you already chose".
if [[ "$USE_CCACHE" == "ON" ]]; then
if ! command -v ccache >/dev/null 2>&1; then
echo "--ccache was passed but ccache is not installed" >&2
exit 1
fi
for lang in C CXX CUDA; do
launcher_var="CMAKE_${lang}_COMPILER_LAUNCHER"
if [[ -n "${!launcher_var:-}" ]]; then
echo "$launcher_var=${!launcher_var} is set; leaving the $lang launcher alone."
continue
fi
CMAKE_ARGS+=("-D${launcher_var}=ccache")
done
fi
if [[ "$ENGINE_ENABLE_HIP" == "ON" ]]; then
CMAKE_ARGS+=(
-DCMAKE_C_COMPILER="$HIP_CLANG_C"
-DCMAKE_CXX_COMPILER="$HIP_CLANG_CXX"
# GPU_BUILD_TARGETS/AMDGPU_TARGETS are sticky cache entries set by
# hip-config from GPU_TARGETS; without -U a previous configure's arch
# list would win over a new --gpu-targets value.
-UGPU_BUILD_TARGETS
-UAMDGPU_TARGETS
-DGPU_TARGETS="$GPU_TARGETS"
)
if [[ -n "$HIP_VMM" ]]; then
if [[ "$HIP_VMM" == "on" ]]; then
CMAKE_ARGS+=(-DGGML_HIP_NO_VMM=OFF)
else
CMAKE_ARGS+=(-DGGML_HIP_NO_VMM=ON)
fi
echo "HIP virtual memory management: $HIP_VMM"
fi
fi
if [[ "$ENGINE_ENABLE_CUDA" == "ON" && -n "$CUDA_ARCH" ]]; then
CMAKE_ARGS+=(
# CMAKE_CUDA_ARCHITECTURES is a sticky cache entry; -U it so a previous
# configure's arch list does not win over a new --cuda-arch value
# (mirrors the HIP --gpu-targets handling above).
-UCMAKE_CUDA_ARCHITECTURES
-DCMAKE_CUDA_ARCHITECTURES="$CUDA_ARCH"
)
fi
# RUNNER is empty unless --conda-env is used, and TARGETS is empty unless
# --target is used. bash 3.2 (stock macOS /bin/bash) and bash < 4.4 report an
# empty array as unbound under `set -u`; the ${arr[@]+"${arr[@]}"} form expands
# to nothing instead of failing.
${RUNNER[@]+"${RUNNER[@]}"} cmake "${CMAKE_ARGS[@]}"
BUILD_CMD=(${RUNNER[@]+"${RUNNER[@]}"} cmake --build "$BUILD_DIR" --parallel "$JOBS")
for target in ${TARGETS[@]+"${TARGETS[@]}"}; do
BUILD_CMD+=(--target "$target")
done
"${BUILD_CMD[@]}"