[package] name = "solitaire_app" version.workspace = true license.workspace = true edition.workspace = true [[bin]] name = "solitaire_app" path = "src/main.rs" # `cdylib` is what cargo-apk packages into `libsolitaire_app.so` for # Android — the activity dlopens the shared object and calls into it. # `rlib` lets the bin target above link the library normally on # desktop. Both produce the same code; only the linkage form differs. [lib] name = "solitaire_app" path = "src/lib.rs" crate-type = ["cdylib", "rlib"] [dependencies] bevy = { workspace = true } solitaire_engine = { workspace = true } solitaire_data = { workspace = true } # Desktop-only deps. `keyring`'s default-store init only matters on # platforms with a real keychain backend (Linux Secret Service, # macOS Keychain, Windows Credential Store), and its transitive # `rpassword` uses `libc::__errno_location` — a symbol Android's # bionic doesn't expose. `winit` is promoted from a transitive # Bevy 0.18 → bevy_winit 0.18 → winit 0.30 dep to a direct dep so # the `Window::icon` wiring in `set_window_icon` can construct # `winit::window::Icon` values (bevy_winit 0.18 doesn't re-export # `Icon`). Android draws its launcher icon from the APK manifest, # so neither dep matters there. Target-gating keeps `cargo apk # build` viable; the desktop call sites have their own # `cfg(not(target_os = "android"))` guards. [target.'cfg(not(target_os = "android"))'.dependencies] keyring = { workspace = true } winit = { version = "0.30", default-features = false } # `tiny-skia` is already in the workspace deps for `solitaire_engine`; # `solitaire_app` consumes it directly only on the desktop icon path # (PNG → raw RGBA decode for `set_window_icon`). tiny-skia = { workspace = true } # --- Android packaging metadata (read by `cargo-apk`) ------------------- # # Pinning these values inside the repo means a contributor running # `cargo apk build -p solitaire_app --target x86_64-linux-android` # does not need to install whatever SDK version cargo-apk happens to # default to today. The numbers track the SDK we install in the dev # setup script: target SDK 34 (Android 14, current Play Store target), # min SDK 26 (Android 8, the lowest Bevy 0.18 supports cleanly with # the wgpu / GLES path). # # Asset path is `../assets` so the same directory the desktop build # already uses ships into the APK without copy-tree gymnastics. # `apk_name` keeps the output filename predictable across machines. [package.metadata.android] package = "com.solitairequest.app" apk_name = "solitaire-quest" build_targets = ["aarch64-linux-android", "armv7-linux-androideabi", "x86_64-linux-android"] assets = "../assets" # Density-bucketed launcher icons. `aapt` processes `res/mipmap-*/` and # packages them into the APK; the launcher selects the best-fit bucket # for the device screen density. Sizes used: # mdpi (1×, 48 dp) → 48 px (exact) # hdpi (1.5×, 72 dp) → 64 px (88 %, aapt scales up slightly) # xhdpi (2×, 96 dp) → 128 px (133 %, aapt scales down) # xxhdpi (3×, 144 dp) → 256 px (178 %, aapt scales down) # xxxhdpi (4×, 192 dp) → 256 px (133 %, aapt scales down) resources = "res" # No `runtime_libs` — we don't ship any precompiled .so files, # the entire app is pure Rust + Bevy. cargo-apk would try to # resolve `runtime_libs//` if set, and fail on a non-existent # arch directory under our package. strip = "strip" [package.metadata.android.sdk] target_sdk_version = 34 min_sdk_version = 26 [[package.metadata.android.uses_feature]] name = "android.hardware.touchscreen" required = true [[package.metadata.android.uses_permission]] name = "android.permission.INTERNET" [package.metadata.android.application] label = "Ferrous Solitaire" # Launcher icon — references the density-bucketed mipmap resource above. icon = "@mipmap/ic_launcher" # `debuggable` defaults to false on release builds; cargo-apk flips it # automatically for debug profiles. Leaving the field unset keeps the # default behaviour. [package.metadata.android.application.activity] # Lock to portrait — the current layout has only been designed and tested # in portrait orientation. Remove (or add a landscape layout) before # enabling auto-rotate. orientation = "portrait"