M12 — the Android client, end to end #2

Merged
bvandeusen merged 86 commits from dev into main 2026-08-21 08:53:58 -04:00
7 changed files with 51 additions and 37 deletions
Showing only changes of commit 5d0de7a682 - Show all commits
Generated
+7
View File
@@ -4213,6 +4213,13 @@ dependencies = [
"uniffi",
]
[[package]]
name = "thoughtsync-uniffi-bindgen"
version = "0.1.0"
dependencies = [
"uniffi",
]
[[package]]
name = "time"
version = "0.3.55"
+1 -1
View File
@@ -4,7 +4,7 @@
# module inside the desktop app (Scribe note 2730).
[workspace]
resolver = "2"
members = ["core", "desktop/src-tauri", "android/ffi"]
members = ["core", "desktop/src-tauri", "android/ffi", "android/bindgen"]
# Shared pins, so two consumers of the core cannot drift onto different versions of
# the same dependency and resolve differently.
+2 -4
View File
@@ -92,10 +92,8 @@ abstract class UniffiBindgen : DefaultTask() {
"cargo",
"run",
"--locked",
"--features",
"bindgen",
"--bin",
"uniffi-bindgen",
"-p",
"thoughtsync-uniffi-bindgen",
"--",
"generate",
"--library",
+25
View File
@@ -0,0 +1,25 @@
[package]
name = "thoughtsync-uniffi-bindgen"
version = "0.1.0"
description = "Generates the Kotlin bindings for thoughtsync-ffi"
authors = ["bvandeusen"]
edition = "2021"
# A crate whose ONLY dependency is uniffi itself.
#
# This started life as a `[[bin]]` inside thoughtsync-ffi, which failed: building
# it compiled that crate and therefore the core, reqwest, native-tls and
# openssl-sys — for the HOST. The vendored-OpenSSL block in core/Cargo.toml is
# scoped to `cfg(target_os = "android")`, so a host build looks for a system
# OpenSSL that ci-rust-android has no reason to carry, and the generator died
# with "failed to run custom build command for openssl-sys".
#
# Adding libssl-dev to the image would have worked and been wrong: a code
# generator should not link the app's TLS stack to emit Kotlin. Splitting it out
# means the generator compiles ~15 small crates and nothing else.
#
# Still a WORKSPACE MEMBER, deliberately. That is what keeps `uniffi` here and
# `uniffi` linked into the .so on one version from one lockfile — they are two
# halves of one ABI, and a separate lockfile is exactly how they would drift.
[dependencies]
uniffi = { version = "0.32", features = ["cli"] }
+16
View File
@@ -0,0 +1,16 @@
//! The Kotlin generator.
//!
//! Invoked by Gradle (see android/app/build.gradle.kts) as:
//!
//! ```text
//! cargo run --locked -p thoughtsync-uniffi-bindgen -- \
//! generate --library <path/to/libthoughtsync_ffi.so> \
//! --language kotlin --out-dir <build/generated/uniffi>
//! ```
//!
//! `--library` mode reads uniffi's metadata straight out of the compiled artifact,
//! so the generated bindings can never describe a different version of the Rust
//! than the one being packaged.
fn main() {
uniffi::uniffi_bindgen_main()
}
-18
View File
@@ -29,21 +29,3 @@ tokio = { version = "1", features = ["rt-multi-thread"] }
# Display + Error impls for the error enum uniffi turns into a Kotlin exception.
thiserror = "2"
[features]
# The Kotlin generator, off by default.
#
# uniffi's `cli` feature drags in clap, askama and goblin — ~15 crates that exist
# only to serve a three-line binary. Until the Android lane lands, this crate is
# compiled on every DESKTOP push (it is a workspace member, so `cargo clippy
# --all-targets` picks it up), and paying for a code generator on a lane that never
# runs one is the wrong trade. `required-features` on the bin means
# `--all-targets` skips it rather than failing.
#
# Generate bindings with:
# cargo run --features bindgen --bin uniffi-bindgen -- generate ...
bindgen = ["uniffi/cli"]
[[bin]]
name = "uniffi-bindgen"
path = "src/bin/uniffi-bindgen.rs"
required-features = ["bindgen"]
-14
View File
@@ -1,14 +0,0 @@
//! The Kotlin generator, as a binary in THIS workspace.
//!
//! uniffi's generated bindings and the `uniffi` runtime crate linked into the `.so`
//! have to be the same version — they are two halves of one ABI. Running the
//! generator from here guarantees that by construction, because it compiles against
//! the very same dependency. A `cargo install uniffi-bindgen` in the CI image would
//! instead be a second version that has to be kept in step by hand, which is why
//! ci-rust-android deliberately doesn't ship one.
//!
//! Invoked as: cargo run --bin uniffi-bindgen -- generate --library <path/to/.so> \
//! --language kotlin --out-dir <app/src/main/java>
fn main() {
uniffi::uniffi_bindgen_main()
}