Esta página se tradujo automáticamente y puede contener errores. Leer el original en inglés

Documentación

Empaquetado

nsh package convierte una app en algo que puedes instalar: un .app para el simulador de iOS, un .ipa firmado para dispositivos iOS, un .apk firmado para Android, un .app con firma ad hoc para macOS, un directorio y .tar.gz para Linux, un directorio y .zip para Windows, o un sitio estático para la web. No necesita proyecto de Xcode ni Gradle.

  • Una app de Rust (nsh.json nombra su "root") se empaqueta desde su directorio. nsh compila el runner del destino en modo release con tu crate incluido y la raíz montada, sin QuickJS: Cargo, el target de Rust de la plataforma (rustup target add …) y, para Android, el NDK.
  • Una app TSX indica su entrada. Su build de release (minificado, compilado a bytecode de QuickJS, exactamente como lo compila nsh build --release) se coloca junto al runtime precompilado que se distribuye con NSH, por lo que no necesita toolchain de Rust. Una app con un crate propio ("rust" sin "root") obtiene runners compilados con su crate.
# A Rust app, from its directory
nsh package --target ios-simulator --run     # build, install and launch in the simulator
nsh package --target android --run           # build, install and launch on a device or emulator
nsh package --target macos --run             # build and launch on this Mac
nsh package --target linux --run             # build and launch on this machine
nsh package --target windows --run           # build and launch on this machine
nsh package --target web --run               # build, serve on this machine and open in the browser
nsh package --target ios --sign "Apple Development: Jane Doe (ABCDE12345)" --profile Dev.mobileprovision

# A TSX app: the same with its entry
nsh package App.tsx --target ios-simulator --run

El resultado se genera en .nsh/out/ a menos que pases --out. Las secciones siguientes muestran el comando de cada destino para una app de Rust; una app TSX añade su entrada (nsh package App.tsx --target …).

#Metadatos de la app: nsh.json

nsh package lee nsh.json en el directorio de la app (junto al archivo de entrada de una app TSX). nsh init escribe uno:

{
  "name": "Gallery",
  "id": "com.example.gallery",
  "version": "1.0.0",
  "build": 1,
  "icon": "icon.png"
}
Clave Tipo Valor por defecto Uso
name cadena el nombre del directorio de la entrada El nombre visible bajo el icono (CFBundleDisplayName, android:label en Android) y el nombre del archivo de salida.
id cadena obligatorio El identificador de bundle / nombre de paquete de Android, en formato DNS inverso bajo un dominio que te pertenezca. También da nombre al lugar donde la app guarda su almacenamiento, de modo que cada app tiene el suyo. nsh package y nsh publish avisan sobre el marcador de posición com.example..
version cadena "1.0.0" La versión visible para el usuario (CFBundleShortVersionString, versionName).
build número 1 El número de compilación (CFBundleVersion, versionCode). Increméntalo en cada versión que subas.
icon cadena ninguno Un PNG cuadrado, idealmente de 1024×1024, relativo a nsh.json.

nsh.json también contiene rust y root (los crates de la app y su componente raíz, Compilar con Rust), theme y appearance, tailwind (consulta Tailwind) y capabilities (consulta Sandbox y capacidades); Estructura del proyecto enumera todas las claves. Las claves desconocidas producen un error.

Cada una de las claves anteriores se puede sobrescribir en la línea de comandos, lo cual es útil en CI:

nsh package --target android --app-version 1.4.0 --build 42

#Opciones

Opción Descripción
--target <ios | ios-simulator | android | macos | linux | windows | web> Para qué compilar (obligatorio).
-o, --out <dir> Directorio de salida. Por defecto .nsh/out.
--name <name> Nombre visible.
--id <id> Identificador de bundle, como com.example.app.
--app-version <version> Versión, como 1.2.0.
--build <n> Número de compilación.
--icon <png> Icono de la app: un PNG cuadrado, idealmente de 1024×1024.
--sign <identity> iOS: la identidad de firma de código para dispositivos.
--profile <file> iOS: el perfil de aprovisionamiento para dispositivos (.mobileprovision).
--keystore <file> Android: un keystore de release (por defecto: la clave de debug).
--key-alias <alias> Android: el alias de la clave en el keystore.
--keystore-password <password> Android: la contraseña del keystore; también se lee de NSH_KEYSTORE_PASSWORD.
--abi <abi> Android: las ABI del APK, repetidas o separadas por comas (por defecto: arm64-v8a y armeabi-v7a).
--run Instalar y ejecutar después: en el simulador de iOS, o en el dispositivo o emulador Android que adb detecte; las apps de macOS, Linux y Windows se ejecutan en esta máquina; un sitio web se sirve en esta máquina y se abre en el navegador. No disponible para --target ios.

#Simulador de iOS

nsh package --target ios-simulator --run

Escribe .nsh/out/<Name>.app, con firma ad hoc (el simulador necesita una firma, pero no una identidad). Con --run arranca un simulador si no hay ninguno en ejecución, instala la app y la lanza. Requiere Xcode.

#Dispositivos iOS

nsh package --target ios \
  --sign "Apple Distribution: Example Inc (ABCDE12345)" \
  --profile AppStore.mobileprovision

Escribe .nsh/out/<Name>.ipa, listo para TestFlight, para las herramientas de subida a App Store o para la instalación directa (según el perfil). Qué ocurre:

  • El perfil de aprovisionamiento se copia en la app como embedded.mobileprovision.
  • Los entitlements provienen del perfil. NSH comprueba que el identificador de aplicación del perfil cubra el id de la app (funcionan perfiles comodín como TEAMID.* o TEAMID.com.example.*) y, en caso contrario, se detiene con un error.
  • La app se firma con codesign usando la identidad y después se comprime en un .ipa (Payload/<Name>.app).

Encuentra tus identidades con:

security find-identity -v -p codesigning

Sin --sign y --profile, NSH escribe un .nsh/out/<Name>.app sin firmar y te lo indica; no se puede instalar en un dispositivo tal cual.

La app admite iPhone y iPad, en vertical y horizontal (vertical invertido solo en iPad), y requiere iOS 15.0 o posterior.

#Android

nsh package --target android --run

Escribe .nsh/out/<Name>.apk. El APK se ensambla directamente con las herramientas de compilación del SDK (aapt2, zipalign, apksigner), sin Gradle. Requisitos:

  • El SDK de Android, localizado mediante ANDROID_HOME (o ANDROID_SDK_ROOT, o ~/Library/Android/sdk), con build tools y el paquete platforms;android-35. NSH te indica el comando sdkmanager cuando falta alguno.
  • Un JDK, para crear el keystore de debug la primera vez.
  • Para una app de Rust, el NDK de Android (sdkmanager "ndk;<version>", o ANDROID_NDK_HOME), que compila su libnsh.so.

La app tiene como objetivo la API 35 y requiere la API 28 (Android 9) o posterior. Contiene código nativo para las ABI de los teléfonos, arm64-v8a y armeabi-v7a; con --run, también la del dispositivo, como el x86_64 de un emulador. --abi las elige tú mismo, por ejemplo --abi arm64-v8a solo para teléfonos de 64 bits, el APK más pequeño:

nsh package --target android --abi arm64-v8a

#Firma para release

Sin --keystore, el APK se firma con la clave de debug estándar (~/.android/debug.keystore, que se crea si no existe), y NSH avisa de que no sirve para publicar en tiendas. Para un release, crea un keystore una sola vez y pásalo:

keytool -genkeypair -v -keystore release.jks -alias upload -keyalg RSA -keysize 2048 -validity 10000

NSH_KEYSTORE_PASSWORD=… nsh package --target android \
  --keystore release.jks --key-alias upload

Prefiere la variable de entorno a --keystore-password para que la contraseña no acabe en el historial de tu shell.

#macOS

nsh package --target macos --run

Escribe .nsh/out/<Name>.app: el ejecutable en Contents/MacOS/, y nsh/assets/…, nsh/app.json (el título de la ventana y la apariencia de la app) y, en una app TSX, su nsh/bundle.nshc en Contents/Resources/. La app tiene firma ad hoc y requiere macOS 14 o posterior; para distribuirla, fírmala con un Developer ID y notarízala. Consulta macOS.

#Linux

nsh package --target linux --run

Escribe .nsh/out/<Name>/ (el ejecutable <Name>, nsh/assets/…, nsh/app.json con el título de la ventana y el id de la aplicación, el nsh/bundle.nshc de una app TSX, <id>.desktop y el icono <id>.png) y lo mismo que .nsh/out/<Name>.tar.gz. Empaqueta en Linux: el runner se compila para la máquina en la que se compila. GTK 4 (4.14 o posterior), Pango y WebKitGTK 6.0 (para las web views) deben estar instalados donde se ejecute la app. Para su instalación y la entrada de escritorio: Linux.

#Windows

nsh package --target windows --run

Escribe .nsh\out\<Name>\ (el ejecutable <Name>.exe con el icono de la app, nsh\assets\…, nsh\app.json con el título de la ventana, el id de la app, la versión y la apariencia, y el nsh\bundle.nshc de una app TSX) y lo mismo que .nsh\out\<Name>.zip. Una app TSX no necesita herramientas; el runner de una app de Rust se compila con Visual Studio Build Tools. Empaqueta en Windows: el runner se compila para la máquina en la que se compila, y solo Windows puede incrustar el icono. La app se ejecuta desde donde se copie su directorio; no se instala nada. Consulta Windows.

#Web

nsh package --target web --run

Escribe .nsh/out/<Name>/, un sitio estático: index.html, manifest.webmanifest, el script de la página (nsh.<digest>.js) y nsh.<digest>.wasm (el motor y el crate de una app de Rust; en una app TSX, el runtime, junto al módulo ES de la app app.<digest>.js), sus assets e iconos, cada uno con un nombre derivado de su contenido para que los hosts puedan almacenarlos en caché de forma indefinida. Despliega el directorio en cualquier servidor web o CDN; --run lo sirve en http://127.0.0.1:4173/ para que lo abras. Cabeceras de caché e incrustación: Web.

#Iconos

Proporciona un PNG cuadrado, idealmente de 1024×1024, en nsh.json ("icon": "icon.png") o con --icon:

  • iOS: compilado por actool de Xcode en el catálogo de assets de la app (Assets.car), que deriva todos los tamaños que necesita iOS.
  • Android: redimensionado a 192×192 y usado como icono del launcher (mipmap-xxxhdpi).
  • macOS: convertido por sips a AppIcon.icns.
  • Linux: copiado como <id>.png, que el archivo .desktop nombra como su Icon.
  • Windows: redimensionado de 16 a 64 píxeles y a 256 píxeles e incrustado en el ejecutable como su icono, que muestran la ventana, el Explorador y la barra de tareas.
  • Web: redimensionado a 32 píxeles (el favicon), 180 (apple-touch-icon), 192 y 512 (el manifiesto de la aplicación web).

Sin icono, el sistema muestra el suyo por defecto.

#Qué contiene

El paquete de una app de Rust es su runner, compilado con tu crate y su raíz montada, y los assets que registran sus crates (assets!()). El paquete de una app TSX contiene su bytecode, su capabilities.json (cuando declara capacidades) y los assets que importa, junto al runtime precompilado:

Destino Runtime Una app TSX
iOS el ejecutable nsh-ios-app <Name>.app/nsh/bundle.nshc, nsh/assets/…
Android classes.dex, lib/<abi>/libnsh.so (sin símbolos, almacenado sin comprimir, alineado a 16 KB) assets/nsh/bundle.nshc, assets/nsh/assets/…
macOS el ejecutable nsh-macos-app, renombrado a <Name> <Name>.app/Contents/Resources/nsh/bundle.nshc, nsh/assets/…
Linux el ejecutable nsh-linux-app, renombrado a <Name> <Name>/nsh/bundle.nshc, nsh/assets/…
Windows el ejecutable nsh-windows-app.exe, renombrado a <Name>.exe <Name>\nsh\bundle.nshc, nsh\assets\…
Web nsh.<digest>.wasm, nsh.<digest>.js <Name>/app.<digest>.js, assets/…, index.html

Una app empaquetada no registra componentes nativos; para ellos, incrusta NSH en tu propia app.

#Localizar el runtime

Una app de Rust compila sus propios runners. Para las apps TSX, nsh package busca el runtime precompilado junto a la CLI (bin/../runtime en la distribución). En un checkout de NSH usa target/<triple>/<profile> y target/android/<profile>, con el perfil de la propia CLI (una CLI de debug usa runtimes de debug): compílalos con cargo build -p nsh-ios-app --target aarch64-apple-ios-sim (o aarch64-apple-ios para dispositivos) y cargo xtask android (añade --release para una CLI de release); nsh-macos-app (en macOS), nsh-linux-app (en Linux) y nsh-windows-app (en Windows) se compilan para esta máquina en target/<profile> (cargo build -p nsh-macos-app, cargo build -p nsh-linux-app, cargo build -p nsh-windows-app); el runtime web se compila con el perfil web sea cual sea el de la CLI, en target/wasm32-unknown-unknown/web/. La variable de entorno NSH_RUNTIME apunta la CLI a otro directorio organizado como el runtime/ de la distribución (ios/iphoneos, ios/iphonesimulator, android/release, macos, linux, windows, gpui, web, …).

#Véase también