build(android): Cargo configuration, crate-type cdylib and android_main entrypoint #42

Open
opened 2026-10-25 13:49:39 +01:00 by harald · 1 comment
Owner

Description

To enable building ink-notes for Android, the workspace must be configured to produce a dynamic C library (cdylib) alongside the desktop binary, and provide an entrypoint that binds winit to Android's activity lifecycle.

Scope of Work

  1. Update Cargo.toml:
    • Add crate-type = ["cdylib", "rlib"] under [lib].
    • Add conditional target dependencies for cfg(target_os = "android"): android-activity, winit (with matching Android feature flags to current eframe), and android_logger.
    • Configure [package.metadata.android] with package identifier eu.pansi.inknotes, min SDK 26, target SDK 34.
  2. Abstract application entrypoint:
    • Ensure the core application initialization logic lives in lib.rs.
    • Keep src/main.rs guarded with #[cfg(not(target_os = "android"))] for desktop execution.
    • Implement #[no_mangle] fn android_main(app: AndroidApp) in src/lib.rs (guarded with #[cfg(target_os = "android")]).
    • Configure eframe::NativeOptions with options.event_loop_builder passing builder.with_android_app(app).
    • Initialize android_logger at start of android_main.

Acceptance Criteria

  • cargo check --target aarch64-linux-android succeeds without compiler errors.
  • Desktop builds (cargo build) continue to compile and run unaffected.
### Description To enable building `ink-notes` for Android, the workspace must be configured to produce a dynamic C library (`cdylib`) alongside the desktop binary, and provide an entrypoint that binds `winit` to Android's activity lifecycle. ### Scope of Work 1. Update `Cargo.toml`: - Add `crate-type = ["cdylib", "rlib"]` under `[lib]`. - Add conditional target dependencies for `cfg(target_os = "android")`: `android-activity`, `winit` (with matching Android feature flags to current `eframe`), and `android_logger`. - Configure `[package.metadata.android]` with package identifier `eu.pansi.inknotes`, min SDK 26, target SDK 34. 2. Abstract application entrypoint: - Ensure the core application initialization logic lives in `lib.rs`. - Keep `src/main.rs` guarded with `#[cfg(not(target_os = "android"))]` for desktop execution. - Implement `#[no_mangle] fn android_main(app: AndroidApp)` in `src/lib.rs` (guarded with `#[cfg(target_os = "android")]`). - Configure `eframe::NativeOptions` with `options.event_loop_builder` passing `builder.with_android_app(app)`. - Initialize `android_logger` at start of `android_main`. ### Acceptance Criteria - `cargo check --target aarch64-linux-android` succeeds without compiler errors. - Desktop builds (`cargo build`) continue to compile and run unaffected.
Author
Owner

Corrections after checking the code (planned for the future, not started)

  • ink-notes does not use eframe. It drives winit 0.29 (vendored and patched in vendor/winit), egui-winit 0.27 and wgpu 0.19 directly, so there is no eframe::NativeOptions. On Android:
    • enable the winit feature android-native-activity;
    • build the event loop with EventLoopBuilder::new().with_android_app(app) (winit::platform::android::EventLoopBuilderExtAndroid).
    • The Wayland patch in vendor/winit does not affect Android.
  • There is no InkNotesApp struct. The whole app is one event loop in src/main.rs (~4300 lines, fn main plus helpers). src/lib.rs only exports the modules. The first and largest step is to move the event loop into the library, e.g. ink_notes::run(event_loop, options), so that both main() and android_main() call it. The desktop behaviour must not change.
  • Several dependencies are Linux/desktop only and have to be gated with cfg(not(target_os = "android")) or replaced:
    • octotablet (pen input, see #44)
    • wayland-client, wayland-backend and wayland-protocols (on-screen keyboard, src/osk.rs)
    • arboard (clipboard)
    • webbrowser
    • the self-updater (src/updater.rs)
    • the built-in file picker that reads XDG user dirs (src/file_picker.rs)
    • fs2 file locks (probably fine, to be checked)
  • wgpu on Android must create the surface only after Resumed, and drop it on Suspended. Currently the window and surface are created once at startup.
  • android_logger is optional. The app logs with eprintln!, which goes nowhere on Android, so logging would need to switch to log.

Revised acceptance criteria stay the same:

  • cargo check --target aarch64-linux-android passes.
  • The desktop build and its tests are unchanged.
**Corrections after checking the code** (planned for the future, not started) - ink-notes does not use **eframe**. It drives winit 0.29 (vendored and patched in `vendor/winit`), egui-winit 0.27 and wgpu 0.19 directly, so there is no `eframe::NativeOptions`. On Android: - enable the winit feature `android-native-activity`; - build the event loop with `EventLoopBuilder::new().with_android_app(app)` (`winit::platform::android::EventLoopBuilderExtAndroid`). - The Wayland patch in `vendor/winit` does not affect Android. - There is no `InkNotesApp` struct. The whole app is one event loop in `src/main.rs` (~4300 lines, `fn main` plus helpers). `src/lib.rs` only exports the modules. The first and largest step is to move the event loop into the library, e.g. `ink_notes::run(event_loop, options)`, so that both `main()` and `android_main()` call it. The desktop behaviour must not change. - Several dependencies are Linux/desktop only and have to be gated with `cfg(not(target_os = "android"))` or replaced: - `octotablet` (pen input, see #44) - `wayland-client`, `wayland-backend` and `wayland-protocols` (on-screen keyboard, `src/osk.rs`) - `arboard` (clipboard) - `webbrowser` - the self-updater (`src/updater.rs`) - the built-in file picker that reads XDG user dirs (`src/file_picker.rs`) - `fs2` file locks (probably fine, to be checked) - wgpu on Android must create the surface only after `Resumed`, and drop it on `Suspended`. Currently the window and surface are created once at startup. - `android_logger` is optional. The app logs with `eprintln!`, which goes nowhere on Android, so logging would need to switch to `log`. Revised acceptance criteria stay the same: - `cargo check --target aarch64-linux-android` passes. - The desktop build and its tests are unchanged.
Sign in to join this conversation.
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: harald/ink-notes#42