voice_audio_multi/scripts/build_xcframework.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

325 lines
9 KiB
Bash

#!/usr/bin/env bash
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
BUILD_ROOT="$REPO_ROOT/build/xcframework"
OUTPUT="$BUILD_ROOT/AudioCpp.xcframework"
BUILD_TYPE="Release"
ARCHS="$(uname -m)"
DEPLOYMENT_TARGET="13.3"
JOBS="$(sysctl -n hw.logicalcpu 2>/dev/null || echo 8)"
CLEAN="OFF"
LLAMAFILE="ON"
NATIVE_CPU="ON"
AUDIOCPP_DEPLOYMENT_BUILD="OFF"
AUDIOCPP_BUILD_NATIVE_MODEL_MANAGER="OFF"
AUDIOCPP_USE_SYSTEM_OPENSSL="OFF"
AUDIOCPP_BORINGSSL_ARCHIVE=""
AUDIOCPP_MODEL_SET="full"
AUDIOCPP_MODELS=""
usage() {
cat <<'EOF'
Usage: scripts/build_xcframework.sh [options]
Build audio.cpp as a macOS static XCFramework.
Options:
--output <path> Output XCFramework path.
Default: build/xcframework/AudioCpp.xcframework
--build-root <path> Intermediate build root.
Default: build/xcframework
--build-type <type> CMake build type.
Default: Release
--deployment-target <version>
Minimum macOS deployment target.
Default: 13.3
--archs "<list>" Space or comma separated macOS architectures.
Default: current machine architecture
--universal Build arm64 and x86_64, then lipo a universal macOS lib.
--clean Remove intermediate/output directories first.
--llamafile ON|OFF Enable ggml llamafile SGEMM.
Default: ON
--native-cpu ON|OFF Build ggml CPU kernels with native host ISA flags.
Default: ON
--deployment-build Embed package specs for standalone GGUF/model loading.
--native-model-manager
Build native model manager and managed WebUI downloads.
--system-openssl Use system OpenSSL for native model management.
--boringssl-archive <path>
Use a local BoringSSL source archive for native model
management instead of downloading at configure time.
--model-set full|core|custom
Model composite to build.
Default: full
--models "<list>" Comma or semicolon separated model targets when
--model-set custom is used.
-j, --jobs <n> Parallel build jobs.
-h, --help Show this help.
Examples:
scripts/build_xcframework.sh
scripts/build_xcframework.sh --universal
scripts/build_xcframework.sh --output /tmp/AudioCpp.xcframework
EOF
}
while [[ $# -gt 0 ]]; do
case "$1" in
--output)
OUTPUT="$2"
shift 2
;;
--build-root)
BUILD_ROOT="$2"
shift 2
;;
--build-type)
BUILD_TYPE="$2"
shift 2
;;
--deployment-target)
DEPLOYMENT_TARGET="$2"
shift 2
;;
--archs)
ARCHS="$2"
shift 2
;;
--universal)
ARCHS="arm64 x86_64"
shift
;;
--clean)
CLEAN="ON"
shift
;;
--llamafile)
LLAMAFILE="$2"
shift 2
;;
--native-cpu)
NATIVE_CPU="$2"
shift 2
;;
--deployment-build)
AUDIOCPP_DEPLOYMENT_BUILD="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
;;
-j|--jobs)
JOBS="$2"
shift 2
;;
-h|--help)
usage
exit 0
;;
*)
echo "Unknown argument: $1" >&2
usage >&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
if [[ "$(uname -s)" != "Darwin" ]]; then
echo "audio.cpp XCFramework builds require macOS." >&2
exit 1
fi
for tool in cmake xcodebuild libtool lipo xcrun; do
if ! command -v "$tool" >/dev/null 2>&1; then
echo "Required tool not found on PATH: $tool" >&2
exit 1
fi
done
case "$LLAMAFILE" in
ON|OFF) ;;
on) LLAMAFILE="ON" ;;
off) LLAMAFILE="OFF" ;;
*)
echo "--llamafile must be ON or OFF" >&2
exit 1
;;
esac
case "$NATIVE_CPU" in
ON|OFF) ;;
on) NATIVE_CPU="ON" ;;
off) NATIVE_CPU="OFF" ;;
*)
echo "--native-cpu must be ON or OFF" >&2
exit 1
;;
esac
ARCHS="${ARCHS//,/ }"
read -r -a ARCH_LIST <<< "$ARCHS"
if [[ ${#ARCH_LIST[@]} -eq 0 ]]; then
echo "No architectures requested." >&2
exit 1
fi
GENERATOR=""
if command -v ninja >/dev/null 2>&1; then
GENERATOR="Ninja"
fi
ARTIFACT_ROOT="$BUILD_ROOT/artifacts"
HEADER_DIR="$ARTIFACT_ROOT/Headers"
UNIVERSAL_LIB="$ARTIFACT_ROOT/libMiniTTS.a"
if [[ "$CLEAN" == "ON" ]]; then
rm -rf "$BUILD_ROOT" "$OUTPUT"
fi
mkdir -p "$ARTIFACT_ROOT"
rm -rf "$HEADER_DIR"
mkdir -p "$HEADER_DIR"
ditto "$REPO_ROOT/include" "$HEADER_DIR"
ditto "$REPO_ROOT/external/ggml/include" "$HEADER_DIR"
archive_for_arch() {
local arch="$1"
local build_dir="$BUILD_ROOT/macos-$arch"
local out_dir="$ARTIFACT_ROOT/macos-$arch"
local out_lib="$out_dir/libMiniTTS.a"
mkdir -p "$out_dir"
echo "==> Configuring audio.cpp for macOS $arch"
local cmake_cmd=(
cmake
-S "$REPO_ROOT" \
-B "$build_dir" \
-DCMAKE_BUILD_TYPE="$BUILD_TYPE" \
-DCMAKE_OSX_ARCHITECTURES="$arch" \
-DCMAKE_OSX_DEPLOYMENT_TARGET="$DEPLOYMENT_TARGET" \
-DENGINE_ENABLE_CUDA=OFF \
-DENGINE_ENABLE_VULKAN=OFF \
-DENGINE_ENABLE_METAL=ON \
-DENGINE_ENABLE_LLAMAFILE="$LLAMAFILE" \
-DENGINE_ENABLE_NATIVE_CPU="$NATIVE_CPU" \
-DGGML_METAL_EMBED_LIBRARY=ON \
-DENGINE_BUILD_TESTS=OFF \
-DENGINE_BUILD_EXAMPLES=OFF \
-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_cmd+=(-DAUDIOCPP_BORINGSSL_ARCHIVE="$AUDIOCPP_BORINGSSL_ARCHIVE")
fi
if [[ -n "$GENERATOR" ]]; then
cmake_cmd+=(-G "$GENERATOR")
fi
"${cmake_cmd[@]}"
echo "==> Building engine_runtime for macOS $arch"
cmake --build "$build_dir" --target engine_runtime -j "$JOBS"
local libs=(
"$build_dir/libengine_runtime.a"
"$build_dir/libcjson_vendor.a"
"$build_dir/libyaml_vendor.a"
"$build_dir/external/sentencepiece/src/libsentencepiece.a"
"$build_dir/external/ggml/src/libggml.a"
"$build_dir/external/ggml/src/libggml-base.a"
"$build_dir/external/ggml/src/libggml-cpu.a"
"$build_dir/external/ggml/src/ggml-metal/libggml-metal.a"
)
local optional_libs=(
"$build_dir/external/ggml/src/ggml-blas/libggml-blas.a"
)
for lib in "${optional_libs[@]}"; do
if [[ -f "$lib" ]]; then
libs+=("$lib")
fi
done
for lib in "${libs[@]}"; do
if [[ ! -f "$lib" ]]; then
echo "Expected static library missing: $lib" >&2
exit 1
fi
done
echo "==> Merging static libraries for macOS $arch"
rm -f "$out_lib"
libtool -static -o "$out_lib" "${libs[@]}"
lipo -info "$out_lib"
}
for arch in "${ARCH_LIST[@]}"; do
archive_for_arch "$arch"
done
rm -f "$UNIVERSAL_LIB"
if [[ ${#ARCH_LIST[@]} -eq 1 ]]; then
cp "$ARTIFACT_ROOT/macos-${ARCH_LIST[0]}/libMiniTTS.a" "$UNIVERSAL_LIB"
else
lipo_inputs=()
for arch in "${ARCH_LIST[@]}"; do
lipo_inputs+=("$ARTIFACT_ROOT/macos-$arch/libMiniTTS.a")
done
lipo -create "${lipo_inputs[@]}" -output "$UNIVERSAL_LIB"
fi
lipo -info "$UNIVERSAL_LIB"
echo "==> Creating XCFramework"
rm -rf "$OUTPUT"
xcodebuild -create-xcframework \
-library "$UNIVERSAL_LIB" \
-headers "$HEADER_DIR" \
-output "$OUTPUT"
echo "Created: $OUTPUT"