An extremely customizable, modular, fast, gpu-accelerated, cross-platform solution for creating user-interfaces minimal effort.
| Platform | Status | Rendering Backend(s) |
|---|---|---|
| Windows 10+ | ✔️ | DX12, Vulkan |
| Windows 8.1- | Vulkan, experimental DX11 | |
| MacOS/iOS | ✔️ | Metal |
| Linux X11/Wayland | ✔️ | Vulkan, GLES3 |
| Android | ✔️ | Vulkan, GLES3 |
Download & install the recommended version of the Android NDK ("Current LTS Release", avoid the beta version).
Install cargo-apk:
cargo install cargo-apkSetting up your device (pick one, real hardware is easier):
- Real hardware
- Enable developer options and enable USB debugging
- Connect your phone via USB cable to your pc
- Emulator (virtual phone):
- Download & install the official Android emulator from google
- Make sure everything is setup correctly with PATH variables etc.
Recommended setup for single codebase applications supporting both mobile & desktop:
File structure (optional)
my_application
├──res
│ └──image.png
├──src
│ ├──app.rs
│ ├──main.rs
│ └──lib.rs
└──Cargo.toml
Cargo.toml
[features]
default = [] # 1
android = ["ndk-glue", "preon_module_wgpu/android"] # 2
[dependencies]
preon_engine = { path = "../preon_engine" }
ndk-glue = { version = "0.3.0", optional = true } # 3
preon_module_wgpu = { path = "../preon_module_wgpu" }
[lib]
crate-type = ["cdylib"] # 4
- Don't enable any features by default
- When the
androidfeature is specified incargo, it will enable thendk-gluedependency and enable theandroidfeature inpreon_module_wgpu- Specify the
ndk-gluedependency, but don't enable it by default. Warning: If you have a tool that checks for dependencies and their updates, ignore the update forndk-glue, aswinitdepends on this specific version.- Android requires a dynamic library for native code.
main.rs
mod app;
// Desktop entry point
fn main() {
app::app();
}app.rs
pub fn app() {
// Regular preon_engine code here
}lib.rs
mod app;
// Mobile entry point
#[cfg_attr(target_os = "android", ndk_glue::main(backtrace = "on"))]
pub fn main() {
app::app();
}Why so weird?
Android needs native code to be a dynamically linked library, so you simply cant use
fn main(). And while we can very easily use the official example to narrow it down to only 2 files, I've found that it can sometimes break IDE &rust-analyzerfunctionality due to the macro. This solution avoids that.
To run your app on android you would run:
cargo apk run --features androidRunning on desktop remains the same:
cargo runTo view stdout (println!, panic!, etc.), run (with your phone connected of course):
adb logcat RustStdoutStderr:D *:S