Files
fn_registry/bash/functions/infra/build_wasm_cpp_app.sh
T

84 lines
2.7 KiB
Bash
Executable File

#!/usr/bin/env bash
# build_wasm_cpp_app — compila app cpp/apps/<name> a WASM via emscripten.
#
# Uso:
# build_wasm_cpp_app.sh <app_name> [--no-budget-check]
#
# Salida: build/wasm/<name>/<name>.{html,js,wasm}
# + <name>.wasm.gz (gzip -9) y <name>.wasm.br (brotli -11 si esta).
#
# Requiere: emsdk activo en el shell (source emsdk/emsdk_env.sh) o que
# exista emsdk/ en la raiz del repo y se autoactive.
set -euo pipefail
APP="${1:?Uso: $0 <app_name> [--no-budget-check]}"
SHIFT_FLAG="${2:-}"
REPO_ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")"/../../.. && pwd)"
SRC_DIR="$REPO_ROOT/cpp/apps/$APP"
BUILD_DIR="$REPO_ROOT/build/wasm/$APP"
if [ ! -d "$SRC_DIR" ]; then
echo "ERROR: $SRC_DIR no existe" >&2
exit 1
fi
# Activate emsdk if not already in PATH.
if ! command -v emcc >/dev/null 2>&1; then
if [ -f "$REPO_ROOT/emsdk/emsdk_env.sh" ]; then
# shellcheck disable=SC1091
source "$REPO_ROOT/emsdk/emsdk_env.sh" >/dev/null 2>&1
fi
fi
if ! command -v emcc >/dev/null 2>&1; then
echo "ERROR: emcc no encontrado. Instala emsdk:" >&2
echo " git clone https://github.com/emscripten-core/emsdk.git" >&2
echo " cd emsdk && ./emsdk install latest && ./emsdk activate latest" >&2
echo " source ./emsdk_env.sh" >&2
exit 1
fi
echo "── emcc: $(emcc --version | head -n1)"
echo "── source: $SRC_DIR"
echo "── build: $BUILD_DIR"
mkdir -p "$BUILD_DIR"
# Build the app directly (NOT the full cpp/ tree). Each app's CMakeLists.txt
# is expected to be self-sufficient as top-level (issue 0072a pattern).
emcmake cmake -S "$SRC_DIR" -B "$BUILD_DIR" -DCMAKE_BUILD_TYPE=MinSizeRel
cmake --build "$BUILD_DIR" --target "$APP" -j
WASM_DIR=$(find "$BUILD_DIR" -name "$APP.wasm" -printf '%h\n' -quit 2>/dev/null || true)
if [ -z "$WASM_DIR" ]; then
echo "ERROR: no se encontro $APP.wasm en $BUILD_DIR" >&2
exit 2
fi
cd "$WASM_DIR"
gzip -9 -k -f "$APP.wasm"
if command -v brotli >/dev/null 2>&1; then
brotli -q 11 -k -f "$APP.wasm"
fi
echo
echo "── Sizes (in $WASM_DIR) ──"
for f in "$APP".html "$APP".js "$APP".wasm "$APP".wasm.gz "$APP".wasm.br; do
[ -f "$f" ] && printf "%-32s %10d bytes\n" "$f" "$(stat -c%s "$f")"
done
# Budget check (1.5 MB gzip soft, 2 MB hard)
if [ "$SHIFT_FLAG" != "--no-budget-check" ]; then
SIZE_GZ=$(stat -c%s "$APP.wasm.gz")
HARD=$((2 * 1024 * 1024))
SOFT=$((1572864)) # 1.5 MB
if [ "$SIZE_GZ" -gt "$HARD" ]; then
echo "$APP.wasm.gz = $SIZE_GZ bytes > $HARD (2 MB hard limit)" >&2
exit 3
elif [ "$SIZE_GZ" -gt "$SOFT" ]; then
echo "$APP.wasm.gz = $SIZE_GZ bytes > $SOFT (1.5 MB soft limit)"
else
echo "$APP.wasm.gz = $SIZE_GZ bytes within soft limit (1.5 MB)"
fi
fi