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
325 lines
9 KiB
Bash
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"
|