Actualiza /compile para que el deploy a Desktop/apps/<app>/ siga la convencion local_files/ del framework: - Copia .exe + ttfs + dlls junto al exe (read-only). - Copia <app_dir>/enrichers/ si existe (excluyendo pycache). - Copia <app_dir>/runtime/ si app.md declara python_runtime: true. Regenera el runtime via tools/freeze_python_runtime.sh windows cuando app.md es mas nuevo que runtime/.lock. - NUNCA toca local_files/ del destino — contiene estado del usuario (DBs, ini, proyectos) que NO se debe perder al recompilar. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
7.2 KiB
/compile — Compila la app actual y la copia al escritorio de Windows
Compila una app del registry para los targets que soporte (Windows via MinGW, Android via Gradle/NDK si esta configurado) y deja el resultado en /mnt/c/Users/lucas/Desktop/apps/<app>/, listo para usar desde Windows.
Pensado para apps C++ del workspace cpp/ (donde ya hay toolchain mingw-w64.cmake y build dir cpp/build/windows/). Si en el futuro hay apps Android (Gradle wrapper o NDK), tambien las detecta.
Argumento
$ARGUMENTS — opcional. Nombre de la app a compilar (ej: chart_demo, registry_dashboard).
- Sin argumento: detectar la app desde
pwd(si estas dentro decpp/apps/<X>/oprojects/*/apps/<X>/). - Si no hay app deducible y no se pasa argumento → listar apps disponibles y pedir nombre.
- Si se pasa argumento, usarlo directamente.
Pasos
1. Resolver la app y su directorio fuente
ROOT=/home/lucas/fn_registry
APP_ARG="$ARGUMENTS"
# Detectar desde CWD si no hay argumento
if [ -z "$APP_ARG" ]; then
CWD="$(pwd)"
case "$CWD" in
"$ROOT"/cpp/apps/*|"$ROOT"/projects/*/apps/*)
APP_ARG="$(basename "$CWD")" ;;
esac
fi
# Si sigue vacio, listar apps y abortar
if [ -z "$APP_ARG" ]; then
echo "Apps disponibles:"
ls "$ROOT"/cpp/apps/ 2>/dev/null
ls "$ROOT"/projects/*/apps/ 2>/dev/null
echo "Uso: /compile <app_name>"
exit 1
fi
# Buscar el directorio real
APP_DIR=""
for cand in "$ROOT/cpp/apps/$APP_ARG" "$ROOT"/projects/*/apps/"$APP_ARG"; do
[ -d "$cand" ] && APP_DIR="$cand" && break
done
if [ -z "$APP_DIR" ]; then
echo "No encuentro app '$APP_ARG' en cpp/apps/ ni projects/*/apps/"
exit 1
fi
echo "App: $APP_ARG"
echo "Dir: $APP_DIR"
2. Detectar targets soportados
Examinar el app.md y los archivos del directorio para decidir que se puede compilar:
- Windows (MinGW): si la app tiene
CMakeLists.txty se registra encpp/CMakeLists.txt(es decir, aparece como subdirectorio encpp/build/windows/apps/<APP>/). Default para apps C++. - Android: si existe
AndroidManifest.xml,build.gradle,build.gradle.ktso carpetaandroid/dentro de$APP_DIR. (Hoy no hay ninguna; saltar silenciosamente.) - Linux (opcional, no por defecto): el build dir
cpp/build/ya genera el binario para Linux. Solo se hace si el usuario lo pide explicitamente.
TARGETS=()
[ -f "$APP_DIR/CMakeLists.txt" ] && TARGETS+=("windows")
if [ -f "$APP_DIR/AndroidManifest.xml" ] || \
[ -f "$APP_DIR/build.gradle" ] || \
[ -f "$APP_DIR/build.gradle.kts" ] || \
[ -d "$APP_DIR/android" ]; then
TARGETS+=("android")
fi
if [ ${#TARGETS[@]} -eq 0 ]; then
echo "No se detecta ningun target compilable en $APP_DIR"
exit 1
fi
echo "Targets: ${TARGETS[*]}"
3. Compilar Windows (cross-compile MinGW)
Solo si windows esta en TARGETS.
BUILD_WIN="$ROOT/cpp/build/windows"
# Configurar build dir si no existe
if [ ! -f "$BUILD_WIN/CMakeCache.txt" ]; then
mkdir -p "$BUILD_WIN"
cmake -S "$ROOT/cpp" -B "$BUILD_WIN" \
-DCMAKE_TOOLCHAIN_FILE="$ROOT/cpp/toolchains/mingw-w64.cmake" \
-DCMAKE_BUILD_TYPE=Release
fi
# Compilar SOLO el target de la app (no todo el arbol)
cmake --build "$BUILD_WIN" --target "$APP_ARG" -j"$(nproc)"
Si el target no existe en CMake (porque la app no esta registrada en cpp/CMakeLists.txt), reportar y proponer registrarla siguiendo cpp_apps.md §5. NO autoregistrarla sin confirmacion del usuario.
4. Copiar a /mnt/c/Users/lucas/Desktop/apps/<APP>/
Layout estandar (convencion local_files/, ver cpp_apps.md §7):
Desktop/apps/<APP>/
├── <APP>.exe ← binario
├── *.ttf, *.dll ← fuentes + DLLs (junto al exe)
├── assets/ ← opcional, copiada del build
├── enrichers/ ← opcional, si <app_dir>/enrichers existe
├── runtime/ ← opcional, si app.md tiene python_runtime: true
└── local_files/ ← creado por la app al primer arranque
NUNCA borrar al recompilar
DEST="/mnt/c/Users/lucas/Desktop/apps/$APP_ARG"
mkdir -p "$DEST"
EXE_SRC="$BUILD_WIN/apps/$APP_ARG/$APP_ARG.exe"
if [ ! -f "$EXE_SRC" ]; then
echo "ERROR: no se ha generado $EXE_SRC"
exit 1
fi
# 1. Binario + TTFs + DLLs (junto al exe del build, copiados por add_imgui_app).
cp -v "$EXE_SRC" "$DEST/"
find "$BUILD_WIN/apps/$APP_ARG" -maxdepth 1 -type f \
\( -name '*.ttf' -o -name '*.dll' \) -exec cp -v {} "$DEST/" \;
# 2. assets/ del build (opcional).
if [ -d "$BUILD_WIN/apps/$APP_ARG/assets" ]; then
rsync -a --delete "$BUILD_WIN/apps/$APP_ARG/assets/" "$DEST/assets/"
fi
# 3. enrichers/ del app_dir (opcional). Excluye __pycache__ + .pyc.
if [ -d "$APP_DIR/enrichers" ]; then
rsync -a --delete --exclude '__pycache__' --exclude '*.pyc' \
"$APP_DIR/enrichers/" "$DEST/enrichers/"
fi
# 4. runtime/ Python embebido (si la app lo declara).
# Lee `python_runtime: true` del frontmatter de app.md.
if grep -q '^python_runtime:[[:space:]]*true' "$APP_DIR/app.md" 2>/dev/null; then
if [ ! -d "$APP_DIR/runtime/python" ] || \
[ "$APP_DIR/app.md" -nt "$APP_DIR/runtime/.lock" ]; then
echo "[freeze] regenerando runtime Python (Windows) para $APP_ARG"
"$APP_DIR/tools/freeze_python_runtime.sh" "$APP_DIR" windows
fi
rsync -a --delete --exclude '__pycache__' --exclude '*.pyc' \
"$APP_DIR/runtime/" "$DEST/runtime/"
fi
# 5. NO TOCAR local_files/. Si existe en $DEST, preservar — contiene
# estado del usuario (DBs, settings, layouts ImGui, proyectos).
echo "OK: $APP_ARG -> $DEST"
[ -d "$DEST/local_files" ] && echo " local_files/ preservado: $(du -sh "$DEST/local_files" | cut -f1)"
5. Compilar Android (solo si TARGETS contiene android)
Hoy no hay apps Android en el registry, asi que esta rama no se ejecuta. Cuando se anada la primera, este es el patron previsto:
if [[ " ${TARGETS[*]} " == *" android "* ]]; then
ANDROID_DIR="$APP_DIR"
[ -d "$APP_DIR/android" ] && ANDROID_DIR="$APP_DIR/android"
cd "$ANDROID_DIR"
if [ -x "./gradlew" ]; then
./gradlew assembleRelease
APK="$(find "$ANDROID_DIR/app/build/outputs/apk/release" -name '*.apk' | head -n1)"
[ -n "$APK" ] && cp -v "$APK" "/mnt/c/Users/lucas/Desktop/apps/$APP_ARG/"
else
echo "android: no hay ./gradlew en $ANDROID_DIR — saltando."
fi
fi
Cuando llegue la primera app Android, este bloque puede ampliarse (firma, ABI splits, etc.).
6. Resumen
Imprime al final una linea por target con:
- Tamano del binario (
ls -lh) - Path final en
/mnt/c/Users/lucas/Desktop/apps/<APP>/ - Nombre del exe/apk
Notas
- El build de Windows usa
cpp/build/windows/(nocpp/build/). El de Linux escpp/build/. Coexisten sin conflicto. - El toolchain
mingw-w64.cmakeya configura linkado estatico (-static-libgcc -static-libstdc++ -lwinpthread) — el.exeresultante es self-contained y no necesita DLLs en el escritorio. - Si se pasa una app que vive en
projects/<proj>/apps/<APP>/, el target CMake sigue siendo<APP>(registrado encpp/CMakeLists.txtconadd_subdirectory(${PROJ_DIR}/apps/<APP> ${CMAKE_BINARY_DIR}/apps/<APP>)). - NO tocar
AdminLocalni instalar nada enProgram Files— solo el escritorio del usuario.