Files
voice-cat/scripts/build-libs.sh
Talon 06a68b441a build(scripts): add per-artifact build scripts staging into dist/
One script per main artifact, all staging into dist/ (overridable via
--dist or VOICECAT_DIST_DIR):

- build-server.sh        server-release preset -> dist/server/
- build-windows-client.sh  windows-client DLL + dotnet publish -> dist/windows-client/
- build-macos-client.sh    XCFramework + xcodebuild VoiceCatMac.app -> dist/macos-client/
- build-libs.sh           libvoicecat per platform -> dist/lib/{macos,ios*,windows}/
                         + dist/lib/VoiceCatCore.xcframework/
- build-all.sh            orchestrator (host-applicable artifacts only)
- common.sh               shared helpers: dist/VCPKG_ROOT resolution, platform
                         guards, logging, --help from header comments

Host-platform guards prevent running the wrong script on the wrong OS.
build-libs.sh and build-macos-client.sh drive the existing validated
clients/apple/scripts/build-xcframework.sh rather than duplicating it.
dist/ added to .gitignore.
2026-06-18 18:52:54 +02:00

175 lines
6.5 KiB
Bash
Executable File

#!/usr/bin/env bash
#
# build-libs.sh — build libvoicecat for each supported client platform and
# stage the artifacts under dist/lib/.
#
# Artifacts per platform:
# macos → dist/lib/macos/ libvoicecat.a + libvoicecat-fat.a + voicecat.h + module.modulemap
# ios → dist/lib/ios-device/ (arm64-ios slice)
# ios-sim → dist/lib/ios-sim/ (arm64-ios-sim slice)
# windows → dist/lib/windows/ voicecat.dll + voicecat.h
# xcframework → dist/lib/VoiceCatCore.xcframework/ (stitched Apple slices)
#
# The Apple slices + XCFramework are produced by clients/apple/scripts/
# build-xcframework.sh (the validated flow); this script drives it and stages
# the outputs. The Windows DLL comes from the `windows-client` preset.
#
# Usage:
# scripts/build-libs.sh # host default (macos on macOS, windows on Windows)
# scripts/build-libs.sh --platform macos
# scripts/build-libs.sh --platform ios
# scripts/build-libs.sh --platform ios-sim
# scripts/build-libs.sh --platform windows
# scripts/build-libs.sh --all-apple # macos + ios + ios-sim + xcframework (macOS host)
# scripts/build-libs.sh --all # everything buildable on this host
# scripts/build-libs.sh --dist /out --no-configure
# scripts/build-libs.sh -h|--help
#
# Platform availability: macos / ios / ios-sim require a macOS host; windows
# requires a Windows host. Requires VCPKG_ROOT.
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
VC_SCRIPT_NAME="build-libs"
source "$SCRIPT_DIR/common.sh"
PLATFORMS=()
DO_CONFIGURE=true
while [[ $# -gt 0 ]]; do
case "$1" in
--dist) vc_set_dist "$2"; shift 2 ;;
--no-configure) DO_CONFIGURE=false; shift ;;
--platform) PLATFORMS+=( "$2" ); shift 2 ;;
--all-apple) PLATFORMs_all_apple=1; shift ;;
--all) PLATFORMS=( all-host ); shift ;;
-h|--help) vc_print_help "$0"; exit 0 ;;
*) vc_die "unknown arg: $1 (try --help)" ;;
esac
done
HOST="$(vc_host_os)"
# --all-apple expands to the three Apple platforms.
if [[ -n "${PLATFORMs_all_apple:-}" ]]; then
PLATFORMS=( macos ios ios-sim )
fi
# Default: host-appropriate single platform.
if [[ ${#PLATFORMS[@]} -eq 0 ]]; then
case "$HOST" in
macos) PLATFORMS=( macos ) ;;
windows) PLATFORMS=( windows ) ;;
*) vc_die "no default library platform for host '$HOST'. Pass --platform explicitly." ;;
esac
fi
# Expand the meta-target.
if [[ " ${PLATFORMS[*]} " == *" all-host "* ]]; then
PLATFORMS=()
case "$HOST" in
macos) PLATFORMS=( macos ios ios-sim ) ;;
windows) PLATFORMS=( windows ) ;;
*) vc_die "--all: nothing buildable on host '$HOST'." ;;
esac
fi
vc_log "dist dir: $VC_DIST_DIR"
vc_log "platforms: ${PLATFORMS[*]}"
# Validate platform availability against host.
for p in "${PLATFORMS[@]}"; do
case "$p" in
macos|ios|ios-sim) [[ "$HOST" == "macos" ]] || vc_die "platform '$p' requires a macOS host." ;;
windows) [[ "$HOST" == "windows" ]] || vc_die "platform '$p' requires a Windows host." ;;
*) vc_die "unknown platform '$p' (try --help)" ;;
esac
done
HAVE_APPLE=false
HAVE_WINDOWS=false
for p in "${PLATFORMS[@]}"; do
case "$p" in
macos|ios|ios-sim) HAVE_APPLE=true ;;
windows) HAVE_WINDOWS=true ;;
esac
done
# ── Apple slices + XCFramework ──────────────────────────────────────────────────
# Stage one slice's .a + headers + module map into dist/lib/<sub>.
stage_apple_slice() {
local preset="$1" sub="$2"
local lib="$VC_REPO_ROOT/build/$preset/lib/libvoicecat.a"
local fat="$VC_REPO_ROOT/build/$preset/lib/libvoicecat-fat.a"
local out; out="$(vc_dist_subdir "lib/$sub")"
[[ -f "$lib" ]] || vc_die "expected $lib not found (did the xcframework build run?)"
cp "$lib" "$out/"
[[ -f "$fat" ]] && cp "$fat" "$out/" || true
cp "$VC_REPO_ROOT/core/include/voicecat.h" "$out/"
cat > "$out/module.modulemap" <<'MM'
module VoiceCatC {
header "voicecat.h"
export *
}
MM
vc_ok "$sub: libvoicecat.a ($(vc_file_size "$lib") bytes) -> $out"
}
if $HAVE_APPLE; then
vc_resolve_vcpkg_root apple-dev
vc_step "build Apple slices via build-xcframework.sh"
ALL_THREE=false
if [[ " ${PLATFORMS[*]} " == *" macos "* && " ${PLATFORMS[*]} " == *" ios "* && " ${PLATFORMS[*]} " == *" ios-sim "* ]]; then
ALL_THREE=true
fi
xcfw_invoke() {
local args=()
$DO_CONFIGURE || args+=( --no-configure )
args+=( "$@" )
"$VC_REPO_ROOT/clients/apple/scripts/build-xcframework.sh" "${args[@]}"
}
if $ALL_THREE; then
xcfw_invoke --all
stage_apple_slice apple-dev macos
stage_apple_slice apple-ios ios-device
stage_apple_slice apple-ios-sim ios-sim
else
for p in "${PLATFORMS[@]}"; do
case "$p" in
macos) xcfw_invoke --preset apple-dev; stage_apple_slice apple-dev macos ;;
ios) xcfw_invoke --preset apple-ios; stage_apple_slice apple-ios ios-device ;;
ios-sim) xcfw_invoke --preset apple-ios-sim; stage_apple_slice apple-ios-sim ios-sim ;;
esac
done
fi
# Stage the stitched XCFramework (whatever slices the last call produced).
XCFW="$VC_REPO_ROOT/clients/apple/VoiceCatCore.xcframework"
[[ -d "$XCFW" ]] || vc_die "xcframework not found at $XCFW"
LIB_DIR="$VC_DIST_DIR/lib"
mkdir -p "$LIB_DIR"
rm -rf "$LIB_DIR/VoiceCatCore.xcframework"
cp -R "$XCFW" "$LIB_DIR/"
vc_ok "VoiceCatCore.xcframework -> $LIB_DIR/"
fi
# ── Windows DLL ─────────────────────────────────────────────────────────────────
if $HAVE_WINDOWS; then
vc_resolve_vcpkg_root windows-client
vc_step "build Windows DLL (preset: windows-client)"
if $DO_CONFIGURE; then
cmake --preset windows-client
fi
cmake --build --preset windows-client
DLL="$VC_REPO_ROOT/build/windows-client/bin/voicecat.dll"
[[ -f "$DLL" ]] || vc_die "expected $DLL not found"
OUT="$(vc_dist_subdir lib/windows)"
cp "$DLL" "$OUT/"
cp "$VC_REPO_ROOT/core/include/voicecat.h" "$OUT/"
vc_ok "windows: voicecat.dll ($(vc_file_size "$DLL") bytes) -> $OUT"
fi
vc_ok "done -> $VC_DIST_DIR/lib"