# /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//`, 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 de `cpp/apps//` o `projects/*/apps//`). - 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 ```bash 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 " 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.txt` y se registra en `cpp/CMakeLists.txt` (es decir, aparece como subdirectorio en `cpp/build/windows/apps//`). Default para apps C++. - **Android**: si existe `AndroidManifest.xml`, `build.gradle`, `build.gradle.kts` o carpeta `android/` 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. ```bash 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. ```bash 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//` Layout estandar (convencion `assets/` + `local_files/`, ver `cpp_apps.md` §7): ``` Desktop/apps// ├── .exe ← binario (top level por convencion Windows DLL) ├── *.dll ← DLLs nativas (Windows las busca junto al exe) ├── assets/ ← read-only, ships con el zip │ ├── *.ttf ← fuentes (vienen de add_imgui_app) │ ├── enrichers/ ← si /enrichers existe │ ├── runtime/ ← Python embed si app.md tiene python_runtime: true │ ├── gx-cli, gx-cli.exe ← si la app necesita un MCP server │ └── ... ← cualquier otro asset distribuible └── local_files/ ← writable, per-PC, creado por la app al primer arranque. NUNCA borrar al recompilar. ``` ```bash DEST="/mnt/c/Users/lucas/Desktop/apps/$APP_ARG" ASSETS="$DEST/assets" mkdir -p "$DEST" "$ASSETS" 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 + DLLs en el top level (Windows DLL search convention). cp -v "$EXE_SRC" "$DEST/" find "$BUILD_WIN/apps/$APP_ARG" -maxdepth 1 -type f -name '*.dll' \ -exec cp -v {} "$DEST/" \; # 2. assets/ — TTFs (las copia add_imgui_app a build//assets/) y # cualquier asset extra del build (build//assets/*). if [ -d "$BUILD_WIN/apps/$APP_ARG/assets" ]; then rsync -a --delete "$BUILD_WIN/apps/$APP_ARG/assets/" "$ASSETS/" fi # 3. enrichers/ del app_dir -> assets/enrichers/. if [ -d "$APP_DIR/enrichers" ]; then rsync -a --delete --exclude '__pycache__' --exclude '*.pyc' \ "$APP_DIR/enrichers/" "$ASSETS/enrichers/" fi # 4. runtime/ Python embebido -> assets/runtime/ (si la app lo declara). 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/" "$ASSETS/runtime/" fi # 5. Otros assets sueltos del app_dir (gx-cli, scripts varios). El # convention es: si vive en / y no es codigo fuente, va a # assets/. Ahora mismo la unica excepcion es gx-cli (graph_explorer). for extra in gx-cli gx-cli.exe; do if [ -f "$APP_DIR/$extra" ]; then cp -v "$APP_DIR/$extra" "$ASSETS/" fi done # 6. 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: ```bash 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//` - Nombre del exe/apk ## Notas - El build de Windows usa `cpp/build/windows/` (no `cpp/build/`). El de Linux es `cpp/build/`. Coexisten sin conflicto. - El toolchain `mingw-w64.cmake` ya configura linkado estatico (`-static-libgcc -static-libstdc++ -lwinpthread`) — el `.exe` resultante es self-contained y no necesita DLLs en el escritorio. - Si se pasa una app que vive en `projects//apps//`, el target CMake sigue siendo `` (registrado en `cpp/CMakeLists.txt` con `add_subdirectory(${PROJ_DIR}/apps/ ${CMAKE_BINARY_DIR}/apps/)`). - NO tocar `AdminLocal` ni instalar nada en `Program Files` — solo el escritorio del usuario.