From 33bd2f2ebe70ad8f560a68d560ecf82ccbd3de1c Mon Sep 17 00:00:00 2001 From: Ryan Gaus Date: Thu, 17 Sep 2026 16:15:08 -0400 Subject: [PATCH 1/2] IMPORTANT(livekit-ffi)!: rename the published UniFFI packages to an FFI identity Every commit before this one keeps the names that the Swift, Android and Flutter SDKs use today. This commit changes them, and it is the only commit that does. Hold it back or move it to its own pull request if the rename is not wanted now. The Swift package and product become LiveKitFFI and RustLiveKitFFI. The Maven artifact becomes io.livekit:livekit-ffi-android with the Kotlin package io.livekit.ffi. The package on pub.dev becomes livekit_ffi. Both surfaces now use the crate name as their UniFFI namespace. Rename the podspec template with the package. The cargo-make task builds its file name from the package name, so the old name would stop the Swift release with a missing template. The repository that holds the Swift framework keeps its current name. Only the package and the product inside it change. BREAKING CHANGE: imports, dependency coordinates and generated module names all change together for the Swift, Android and Flutter SDKs. Before the first release, publish livekit_ffi to pub.dev by hand and set its tag pattern, because pub.dev automates only a package that exists. Also remove the old source directory from the framework repository. --- .changeset/rename_uniffi_packages_to_ffi.md | 26 +++++++++++++ .github/workflows/uniffi-dart-publish.yml | 12 +++--- .github/workflows/uniffi-swift.yml | 4 +- livekit-ffi/Makefile.toml | 12 +++--- livekit-ffi/src/core_modules/runtime.rs | 4 +- livekit-ffi/src/lib.rs | 2 +- livekit-ffi/support/android/README.md | 10 ++--- livekit-ffi/support/android/build.gradle.kts | 2 +- livekit-ffi/support/android/gradle.properties | 10 ++--- .../support/android/settings.gradle.kts | 2 +- livekit-ffi/support/dart/README.md | 10 ++--- livekit-ffi/support/dart/hook/build.dart.tera | 2 +- .../support/dart/test/access_token_test.dart | 2 +- .../support/dart/test/build_version_test.dart | 2 +- livekit-ffi/support/swift/DEBUGGING.md | 38 +++++++++---------- ...I.podspec.tera => LiveKitFFI.podspec.tera} | 0 livekit-ffi/support/swift/README.md | 6 +-- livekit-ffi/uniffi.toml | 10 ++--- 18 files changed, 89 insertions(+), 65 deletions(-) create mode 100644 .changeset/rename_uniffi_packages_to_ffi.md rename livekit-ffi/support/swift/{LiveKitUniFFI.podspec.tera => LiveKitFFI.podspec.tera} (100%) diff --git a/.changeset/rename_uniffi_packages_to_ffi.md b/.changeset/rename_uniffi_packages_to_ffi.md new file mode 100644 index 000000000..8ea3c118f --- /dev/null +++ b/.changeset/rename_uniffi_packages_to_ffi.md @@ -0,0 +1,26 @@ +--- +livekit-ffi: minor +--- + +Rename the published UniFFI packages to an FFI identity. + +Following the `livekit-uniffi` merge, the packages built from +`livekit-ffi/core-modules` are named after the crate that now produces them. No +compatibility aliases are published. + +| | was | now | +|---|---|---| +| Swift package / product | `LiveKitUniFFI` | `LiveKitFFI` | +| Swift FFI module | `RustLiveKitUniFFI` | `RustLiveKitFFI` | +| Maven artifact | `io.livekit:livekit-uniffi-android` | `io.livekit:livekit-ffi-android` | +| Kotlin package | `io.livekit.uniffi` | `io.livekit.ffi` | +| pub.dev package | `livekit_uniffi` | `livekit_ffi` | +| UniFFI namespace | `livekit_uniffi` | `livekit_ffi` | + +**Breaking for the Swift, Android and Flutter SDKs.** Imports, dependency +coordinates and the generated module names all change together. + +The Swift xcframework continues to be hosted at +`livekit/livekit-uniffi-xcframework`; only the package and product names inside +it change. Versions continue from the merged crate, so no published version +goes backwards within a name. diff --git a/.github/workflows/uniffi-dart-publish.yml b/.github/workflows/uniffi-dart-publish.yml index df25a9449..2f34c4278 100644 --- a/.github/workflows/uniffi-dart-publish.yml +++ b/.github/workflows/uniffi-dart-publish.yml @@ -1,6 +1,6 @@ name: UniFFI Dart package -# Publishes the generated livekit_uniffi Dart package to pub.dev on a +# Publishes the generated livekit_ffi Dart package to pub.dev on a # livekit-ffi release, together with the native libraries it loads. # # This is a separate workflow from uniffi-packages.yml because pub.dev's @@ -201,20 +201,20 @@ jobs: # consumer, and pub.dev versions cannot be unpublished. - name: Stage package outside the work tree run: | - rm -rf "$RUNNER_TEMP/livekit_uniffi" - cp -R livekit-ffi/packages/dart "$RUNNER_TEMP/livekit_uniffi" - if find "$RUNNER_TEMP/livekit_uniffi" \( -name 'liblivekit_ffi.*' -o -name 'livekit_uniffi.dll' \) | grep -q .; then + rm -rf "$RUNNER_TEMP/livekit_ffi" + cp -R livekit-ffi/packages/dart "$RUNNER_TEMP/livekit_ffi" + if find "$RUNNER_TEMP/livekit_ffi" \( -name 'liblivekit_ffi.*' -o -name 'livekit_ffi.dll' \) | grep -q .; then echo "Staged package contains a local native library; refusing to publish." >&2 exit 1 fi - name: Validate package - working-directory: ${{ runner.temp }}/livekit_uniffi + working-directory: ${{ runner.temp }}/livekit_ffi run: | dart pub get dart pub publish --dry-run - name: Publish to pub.dev if: ${{ env.PUBLISH_ENABLED == 'true' && !inputs.dry_run }} - working-directory: ${{ runner.temp }}/livekit_uniffi + working-directory: ${{ runner.temp }}/livekit_ffi run: dart pub publish --force diff --git a/.github/workflows/uniffi-swift.yml b/.github/workflows/uniffi-swift.yml index 4a5fac6f1..fe6cefc6d 100644 --- a/.github/workflows/uniffi-swift.yml +++ b/.github/workflows/uniffi-swift.yml @@ -31,8 +31,8 @@ env: CARGO_TERM_COLOR: always HOSTING_REPO: livekit/livekit-uniffi-xcframework # SPM_NAME must match the value in livekit-ffi/Makefile.toml [env]. - SPM_NAME: LiveKitUniFFI - OUTPUT_DIR: livekit-ffi/packages/swift/LiveKitUniFFI + SPM_NAME: LiveKitFFI + OUTPUT_DIR: livekit-ffi/packages/swift/LiveKitFFI jobs: build-and-publish: diff --git a/livekit-ffi/Makefile.toml b/livekit-ffi/Makefile.toml index ef24baf1f..bb241e74f 100644 --- a/livekit-ffi/Makefile.toml +++ b/livekit-ffi/Makefile.toml @@ -17,8 +17,8 @@ PACKAGES_DIR = "./packages" SUPPORT_DIR = "./support" LIB_NAME = "lib${CARGO_MAKE_CRATE_FS_NAME}" TARGET_DIR = "${CARGO_MAKE_CRATE_TARGET_DIRECTORY}" -SPM_NAME = "LiveKitUniFFI" -DART_PACKAGE_NAME = "livekit_uniffi" +SPM_NAME = "LiveKitFFI" +DART_PACKAGE_NAME = "livekit_ffi" # Rendered into pubspec.yaml by dart-generate-manifest. Fail closed: every # profile gets `publish_to: none` (dev packages embed a host dylib and must # never reach pub.dev), and only an explicit release build clears it so @@ -80,7 +80,7 @@ private = true [tasks.android-shared.env] ANDROID_CARGO_OUT_DIR = { source = "${CARGO_MAKE_PROFILE}", mapping = { development = "debug", release = "release", default = "debug" } } -ANDROID_AAR_BASENAME = "livekit-uniffi-android-release" +ANDROID_AAR_BASENAME = "livekit-ffi-android-release" [tasks.build-android] extend = "android-shared" @@ -478,7 +478,7 @@ run_task = "swift-package-flow" # MARK: - Android # -# Output: ${PACKAGES_DIR}/android/livekit-uniffi-android-release.aar +# Output: ${PACKAGES_DIR}/android/livekit-ffi-android-release.aar # # Debugging: cargo make android-package # → debug .so files packaged into the release AAR (unstripped Rust @@ -649,10 +649,10 @@ exec cargo run -p bindgens --features dart-bindgen --bin uniffi-bindgen-dart -- # # packages/dart/ # pubspec.yaml (from support/dart/pubspec.yaml.tera) -# lib/livekit_uniffi.dart +# lib/livekit_ffi.dart # hook/build.dart (from support/dart/hook/build.dart) # LICENSE, README.md, CHANGELOG.md -# liblivekit_uniffi. (dev only: copied local build) +# liblivekit_ffi. (dev only: copied local build) # # Publishing note: pub builds its archive from git's file listing and this # whole tree is gitignored, so `dart pub publish` must run from a copy of diff --git a/livekit-ffi/src/core_modules/runtime.rs b/livekit-ffi/src/core_modules/runtime.rs index 676dc2579..18e62d121 100644 --- a/livekit-ffi/src/core_modules/runtime.rs +++ b/livekit-ffi/src/core_modules/runtime.rs @@ -21,8 +21,8 @@ pub(crate) fn runtime() -> &'static Runtime { RUNTIME.get_or_init(|| { tokio::runtime::Builder::new_multi_thread() .enable_all() - .thread_name("livekit-uniffi") + .thread_name("livekit-ffi-core") .build() - .expect("Failed to build livekit-uniffi tokio runtime") + .expect("Failed to build livekit-ffi core-modules tokio runtime") }) } diff --git a/livekit-ffi/src/lib.rs b/livekit-ffi/src/lib.rs index 8c9612e83..67f8ef3e9 100644 --- a/livekit-ffi/src/lib.rs +++ b/livekit-ffi/src/lib.rs @@ -70,4 +70,4 @@ pub mod build_info; #[cfg(feature = "room-apis")] uniffi::setup_scaffolding!("livekit_ffi"); #[cfg(feature = "core-modules")] -uniffi::setup_scaffolding!("livekit_uniffi"); +uniffi::setup_scaffolding!("livekit_ffi"); diff --git a/livekit-ffi/support/android/README.md b/livekit-ffi/support/android/README.md index 40bc37067..4046d9997 100644 --- a/livekit-ffi/support/android/README.md +++ b/livekit-ffi/support/android/README.md @@ -1,6 +1,6 @@ # LiveKit FFI — Android library -Gradle Android library module that packages UniFFI Kotlin bindings and native `liblivekit_uniffi.so` binaries into an **AAR**. +Gradle Android library module that packages UniFFI Kotlin bindings and native `liblivekit_ffi.so` binaries into an **AAR**. ## Prerequisites @@ -16,7 +16,7 @@ cargo make android-package # debug .so in release A cargo make --profile release android-package # release .so (CI / publishing) ``` -The built AAR is located at: `packages/android/livekit-uniffi-android-release.aar` +The built AAR is located at: `packages/android/livekit-ffi-android-release.aar` In the default (development) profile, Rust builds are unoptimized debug artifacts; `--profile release` additionally applies release Rust flags and runs the size gate. @@ -51,14 +51,14 @@ Or from this directory: Output: ``` -build/outputs/aar/livekit-uniffi-android-release.aar +build/outputs/aar/livekit-ffi-android-release.aar ``` ## App integration ```kotlin dependencies { - implementation("io.livekit:livekit-uniffi-android:x.y.z") + implementation("io.livekit:livekit-ffi-android:x.y.z") } ``` @@ -85,7 +85,7 @@ Depend on the artifact as above, using the `VERSION_NAME` in this module's `grad ```kotlin dependencies { - implementation("io.livekit:livekit-uniffi-android:0.0.1") + implementation("io.livekit:livekit-ffi-android:0.0.1") } ``` diff --git a/livekit-ffi/support/android/build.gradle.kts b/livekit-ffi/support/android/build.gradle.kts index 336054bda..7ba54a372 100644 --- a/livekit-ffi/support/android/build.gradle.kts +++ b/livekit-ffi/support/android/build.gradle.kts @@ -15,7 +15,7 @@ version = providers.gradleProperty("VERSION_NAME").get() val generatedKotlinDir = rootDir.resolve("../../packages/kotlin") android { - namespace = "io.livekit.uniffi" + namespace = "io.livekit.ffi" compileSdk = 34 defaultConfig { diff --git a/livekit-ffi/support/android/gradle.properties b/livekit-ffi/support/android/gradle.properties index c1458643c..909b7589e 100644 --- a/livekit-ffi/support/android/gradle.properties +++ b/livekit-ffi/support/android/gradle.properties @@ -10,13 +10,13 @@ android.nonTransitiveRClass=true GROUP=io.livekit VERSION_NAME=0.0.1 -POM_NAME=LiveKit UniFFI for Android -POM_DESCRIPTION=UniFFI bindings for LiveKit Android SDK -POM_ARTIFACT_ID=livekit-uniffi-android +POM_NAME=LiveKit FFI for Android +POM_DESCRIPTION=UniFFI bindings for the LiveKit Android SDK +POM_ARTIFACT_ID=livekit-ffi-android POM_PACKAGING=aar -POM_URL=https://github.com/livekit/rust-sdks/tree/main/livekit-uniffi -POM_SCM_URL=https://github.com/livekit/rust-sdks/tree/main/livekit-uniffi +POM_URL=https://github.com/livekit/rust-sdks/tree/main/livekit-ffi +POM_SCM_URL=https://github.com/livekit/rust-sdks/tree/main/livekit-ffi POM_SCM_CONNECTION=scm:git:git://github.com/livekit/rust-sdks.git POM_SCM_DEV_CONNECTION=scm:git:ssh://git@github.com/livekit/rust-sdks.git diff --git a/livekit-ffi/support/android/settings.gradle.kts b/livekit-ffi/support/android/settings.gradle.kts index 05b1d7593..111e7eb60 100644 --- a/livekit-ffi/support/android/settings.gradle.kts +++ b/livekit-ffi/support/android/settings.gradle.kts @@ -14,4 +14,4 @@ dependencyResolutionManagement { } } -rootProject.name = "livekit-uniffi-android" +rootProject.name = "livekit-ffi-android" diff --git a/livekit-ffi/support/dart/README.md b/livekit-ffi/support/dart/README.md index 90fd7cb32..b86ec5996 100644 --- a/livekit-ffi/support/dart/README.md +++ b/livekit-ffi/support/dart/README.md @@ -1,7 +1,7 @@ -# livekit_uniffi +# livekit_ffi Dart bindings for the LiveKit Rust SDK core, generated from the -[`livekit-uniffi`](https://github.com/livekit/rust-sdks/tree/main/livekit-uniffi) +[`livekit-ffi`](https://github.com/livekit/rust-sdks/tree/main/livekit-ffi) crate with [UniFFI](https://mozilla.github.io/uniffi-rs/) and [uniffi-dart](https://github.com/Uniffi-Dart/uniffi-dart). @@ -14,7 +14,7 @@ intended to be used directly in applications. The bindings call into a prebuilt Rust dynamic library through Dart's [Native Assets](https://dart.dev/tools/hooks). The package's `hook/build.dart` resolves the library for your target platform at build time, downloading it -from the matching [`livekit-uniffi` release](https://github.com/livekit/rust-sdks/releases) +from the matching [`livekit-ffi` release](https://github.com/livekit/rust-sdks/releases) and verifying its SHA-256 checksum. No Rust toolchain is required to consume this package. @@ -31,10 +31,10 @@ Linux (arm64, x64), and Windows (arm64, x64). This package is generated; do not edit it directly. To build it from source: ```sh -cd rust-sdks/livekit-uniffi +cd rust-sdks/livekit-ffi cargo make dart-package # generates packages/dart with a locally built library ``` -See the [crate README](https://github.com/livekit/rust-sdks/tree/main/livekit-uniffi) +See the [crate README](https://github.com/livekit/rust-sdks/tree/main/livekit-ffi) for details. Issues and pull requests go to [livekit/rust-sdks](https://github.com/livekit/rust-sdks). diff --git a/livekit-ffi/support/dart/hook/build.dart.tera b/livekit-ffi/support/dart/hook/build.dart.tera index 684a24b01..21307443a 100644 --- a/livekit-ffi/support/dart/hook/build.dart.tera +++ b/livekit-ffi/support/dart/hook/build.dart.tera @@ -1,4 +1,4 @@ -// Native Assets build hook for the LiveKit UniFFI Dart bindings. +// Native Assets build hook for the LiveKit FFI Dart bindings. // // The generated bindings call the native library through `@Native` annotations // bound to the asset id `package:/uniffi:livekit_ffi`. This hook diff --git a/livekit-ffi/support/dart/test/access_token_test.dart b/livekit-ffi/support/dart/test/access_token_test.dart index 0fe5e5870..1b8f87e30 100644 --- a/livekit-ffi/support/dart/test/access_token_test.dart +++ b/livekit-ffi/support/dart/test/access_token_test.dart @@ -1,5 +1,5 @@ import 'package:test/test.dart'; -import 'package:livekit_uniffi/livekit_uniffi.dart'; +import 'package:livekit_ffi/livekit_ffi.dart'; void main() { // Exercises real Rust JWT/HMAC logic across the FFI boundary: generate a diff --git a/livekit-ffi/support/dart/test/build_version_test.dart b/livekit-ffi/support/dart/test/build_version_test.dart index 6080ff74d..7640c2385 100644 --- a/livekit-ffi/support/dart/test/build_version_test.dart +++ b/livekit-ffi/support/dart/test/build_version_test.dart @@ -1,5 +1,5 @@ import 'package:test/test.dart'; -import 'package:livekit_uniffi/livekit_uniffi.dart'; +import 'package:livekit_ffi/livekit_ffi.dart'; void main() { // Smoke test for the whole FFI path: the build hook resolves the native diff --git a/livekit-ffi/support/swift/DEBUGGING.md b/livekit-ffi/support/swift/DEBUGGING.md index 653e57859..09774e31b 100644 --- a/livekit-ffi/support/swift/DEBUGGING.md +++ b/livekit-ffi/support/swift/DEBUGGING.md @@ -1,12 +1,12 @@ --- name: uniffi-swift-debug -description: Debug Rust code (livekit-uniffi) through Swift consumers with full Rust stack traces in lldb/Xcode. Use when Rust frames are missing from Xcode/lldb backtraces, when setting breakpoints in .rs files from a Swift app, when building a local debug LiveKitUniFFI xcframework, when linking client-sdk-swift to a local rust-sdks checkout, or when creating debug workspaces or headless lldb test rigs for the UniFFI boundary. +description: Debug Rust code (livekit-ffi) through Swift consumers with full Rust stack traces in lldb/Xcode. Use when Rust frames are missing from Xcode/lldb backtraces, when setting breakpoints in .rs files from a Swift app, when building a local debug LiveKitFFI xcframework, when linking client-sdk-swift to a local rust-sdks checkout, or when creating debug workspaces or headless lldb test rigs for the UniFFI boundary. --- # Debugging Rust through Swift (UniFFI) The published `livekit-uniffi-xcframework` is a release build with `strip = "symbols"` -(see `livekit-uniffi/Cargo.toml`), so lldb has nothing to symbolicate: Xcode shows only +(see `livekit-ffi/Cargo.toml`), so lldb has nothing to symbolicate: Xcode shows only the generated UniFFI Swift glue and bare addresses for Rust. **A locally built debug xcframework has full DWARF** — lldb then shows mixed Swift/Rust backtraces, Rust source listings, stepping, and variables (`frame variable` prints Rust values). @@ -16,7 +16,7 @@ keep the rust-sdks checkout/target dir around, and rebuild the xcframework after Rust change. Quick check that a build is debuggable: `nm -a | grep -c ' OSO '` (> 0 means DWARF refs present; a stripped release build has 0 and ~1k symbols vs ~14k). The binary lives inside the xcframework at -`RustLiveKitUniFFI.xcframework/macos-arm64_x86_64/RustLiveKitUniFFI.framework/RustLiveKitUniFFI` +`RustLiveKitFFI.xcframework/macos-arm64_x86_64/RustLiveKitFFI.framework/RustLiveKitFFI` (platform dir varies, e.g. `ios-arm64`). ## Repo layout, placeholders, and worktrees @@ -56,7 +56,7 @@ copy involved is a git worktree: ## Recipe 1 — build a local debug xcframework ```sh -cd /livekit-uniffi +cd /livekit-ffi cargo make swift-package-debug # macOS only — fastest SPM_PLATFORMS="macos ios" cargo make swift-package-debug # + iOS sim/device ``` @@ -67,8 +67,8 @@ dev-profile `swift-package` task. cargo-make installs `cargo-swift`/`tera` pins automatically on first run. For all Apple platforms instead: `cargo make swift-package` (needs nightly + rust-src for tvOS/visionOS — slow). -Output: `/livekit-uniffi/packages/swift/LiveKitUniFFI/` — an SPM package -wrapping the debug `RustLiveKitUniFFI.xcframework`. +Output: `/livekit-ffi/packages/swift/LiveKitFFI/` — an SPM package +wrapping the debug `RustLiveKitFFI.xcframework`. ## Recipe 2 — point client-sdk-swift at the local package @@ -88,7 +88,7 @@ In ``, replace the released dependency in **both** `Package.sw // before: .package(url: "https://github.com/livekit/livekit-uniffi-xcframework.git", exact: "X.Y.Z"), // after — absolute path to Recipe 1 output: -.package(name: "livekit-uniffi-xcframework", path: "/livekit-uniffi/packages/swift/LiveKitUniFFI"), +.package(name: "livekit-uniffi-xcframework", path: "/livekit-ffi/packages/swift/LiveKitFFI"), ``` Keep the `name:` parameter — `.product(..., package: "livekit-uniffi-xcframework")` @@ -135,7 +135,7 @@ let token = "\(header).\(payload).c2lnbmF0dXJl" let response = TokenSourceResponse(serverURL: URL(string: "wss://example.livekit.cloud")!, participantToken: token) -// Swift app → LiveKit SDK → UniFFI glue → Rust (livekit-uniffi → livekit-api → jsonwebtoken) +// Swift app → LiveKit SDK → UniFFI glue → Rust (livekit-ffi → livekit-api → jsonwebtoken) print("dispatchesAgent: \(response.dispatchesAgent())") ``` @@ -157,8 +157,8 @@ lldb --batch -s lldb-demo.txt ./.build/debug/lk-uniffi-debug-sample ``` Success looks like frames spanning `livekit_api::access_token::Claims::from_unverified` -→ `livekit_uniffi::access_token::token_claims_from_unverified` → `uniffi_core` rustcalls -→ generated `livekit_uniffi.swift` → `TokenSource.swift` → `main.swift`, each with +→ `livekit_ffi::access_token::token_claims_from_unverified` → `uniffi_core` rustcalls +→ generated `livekit_ffi.swift` → `TokenSource.swift` → `main.swift`, each with file:line. If Rust frames show as bare addresses, the dylib is stripped — redo Recipe 1 and confirm the worktree manifests point at it (`swift package resolve` output). @@ -167,12 +167,12 @@ the bindings (e.g. token parsing, not `tokenGenerate`). To debug the rest, skip Recipe 2 and depend on the Recipe 1 package directly: ```swift -dependencies: [.package(path: "/livekit-uniffi/packages/swift/LiveKitUniFFI")], -// target dependency: .product(name: "LiveKitUniFFI", package: "LiveKitUniFFI") +dependencies: [.package(path: "/livekit-ffi/packages/swift/LiveKitFFI")], +// target dependency: .product(name: "LiveKitFFI", package: "LiveKitFFI") ``` -then `import LiveKitUniFFI` and call the generated glue (see the public API in the -package's `Sources/LiveKitUniFFI/livekit_uniffi.swift`) — same boundary, same +then `import LiveKitFFI` and call the generated glue (see the public API in the +package's `Sources/LiveKitFFI/livekit_ffi.swift`) — same boundary, same backtraces, smaller dependency graph. ## Recipe 4 — Xcode debug workspace @@ -186,7 +186,7 @@ client-sdk-swift worktree (folder reference = local package override, same patte - + ``` @@ -203,7 +203,7 @@ Caveats: a symlink — `ln -s /client-sdk-swift` — and pointing the FileRef at the symlink. Verify headlessly before opening Xcode: `xcodebuild -resolvePackageDependencies -workspace -scheme ` - should resolve `LiveKit` to the local path and `LiveKitUniFFI` to the Recipe 1 output. + should resolve `LiveKit` to the local path and `LiveKitFFI` to the Recipe 1 output. - Xcode refuses to open the same SPM package in two workspaces — close other windows. - Rust folder refs must point at the **same ``** that built the xcframework; file:line breakpoints match DWARF paths absolutely. @@ -223,7 +223,7 @@ object ID — grep `project.pbxproj` for `PBXNativeTarget ""`), `BuildableN (`container:` + absolute path to the `.xcodeproj`). Then: ```sh -# package graph: LiveKit → local working copy, LiveKitUniFFI → Recipe 1 output +# package graph: LiveKit → local working copy, LiveKitFFI → Recipe 1 output xcodebuild -resolvePackageDependencies -workspace -scheme # compile/link check without the user's signing identity: xcodebuild build -workspace -scheme -destination 'platform=macOS,arch=arm64' CODE_SIGNING_ALLOWED=NO @@ -262,13 +262,13 @@ Restart Xcode. Undo: `lsregister -u ~/Applications/RustSourceUTI.app && rm -rf ~ Symbolic-name breakpoints survive Rust edits; file:line breakpoints may drift — look up current lines with grep rather than hardcoding. Basename matching also binds in -**every** file with that name — both livekit-uniffi and livekit-api have an +**every** file with that name — both livekit-ffi and livekit-api have an `access_token.rs`, so expect resolved locations (and stops) in each. ## What you can do with this skill Agentic (headless — Claude does it end-to-end and reports the backtrace): -- "Verify my Rust change in livekit-uniffi is actually hit when the Swift SDK parses a +- "Verify my Rust change in livekit-ffi is actually hit when the Swift SDK parses a token" → Recipes 1–3, breakpoint on the changed fn, report `bt` + variables. - "Why does `tokenClaimsFromUnverified` throw for this token?" → Recipe 3 with the user's token string, step through `Claims::from_unverified`, inspect Rust state. diff --git a/livekit-ffi/support/swift/LiveKitUniFFI.podspec.tera b/livekit-ffi/support/swift/LiveKitFFI.podspec.tera similarity index 100% rename from livekit-ffi/support/swift/LiveKitUniFFI.podspec.tera rename to livekit-ffi/support/swift/LiveKitFFI.podspec.tera diff --git a/livekit-ffi/support/swift/README.md b/livekit-ffi/support/swift/README.md index 52e1b29fd..f10e8dd8b 100644 --- a/livekit-ffi/support/swift/README.md +++ b/livekit-ffi/support/swift/README.md @@ -1,10 +1,10 @@ # Swift packaging -Details for the `cargo make swift-package*` tasks. Both modes write to `./packages/swift/LiveKitUniFFI/`. +Details for the `cargo make swift-package*` tasks. Both modes write to `./packages/swift/LiveKitFFI/`. ## Modes -**Debugging** — default profile, produces a `Package.swift` that points at the unzipped xcframework via a relative `path:` so it can be consumed directly from `./packages/swift/LiveKitUniFFI/`. The dylib is an unstripped debug build, so Rust frames show up in lldb/Xcode — see [DEBUGGING.md](./DEBUGGING.md) for the full workflow: +**Debugging** — default profile, produces a `Package.swift` that points at the unzipped xcframework via a relative `path:` so it can be consumed directly from `./packages/swift/LiveKitFFI/`. The dylib is an unstripped debug build, so Rust frames show up in lldb/Xcode — see [DEBUGGING.md](./DEBUGGING.md) for the full workflow: ``` cargo make swift-package-debug # macOS only — fastest @@ -15,7 +15,7 @@ cargo make swift-package # all Apple platforms To consume it from a Swift project (e.g. `client-sdk-swift`), add this dependency entry to its `Package.swift` (and `Package@swift-6.2.swift`): ```swift -.package(name: "livekit-uniffi-xcframework", path: "../rust-sdks/livekit-uniffi/packages/swift/LiveKitUniFFI"), +.package(name: "livekit-uniffi-xcframework", path: "../rust-sdks/livekit-ffi/packages/swift/LiveKitFFI"), ``` Adjust the relative path to match your checkout layout. Don't commit this change — it's purely for local iteration. diff --git a/livekit-ffi/uniffi.toml b/livekit-ffi/uniffi.toml index e0e2d2081..6ed11de23 100644 --- a/livekit-ffi/uniffi.toml +++ b/livekit-ffi/uniffi.toml @@ -1,9 +1,9 @@ [bindings.swift] -ffi_module_name = "RustLiveKitUniFFI" +ffi_module_name = "RustLiveKitFFI" [bindings.kotlin] android = true -package_name = "io.livekit.uniffi" +package_name = "io.livekit.ffi" cdylib_name = "livekit_ffi" # the name of the so file to be loaded # The Kotlin checksum test is off because it fails on ARM devices. @@ -53,8 +53,6 @@ omit_checksums = true [bindings.dart] # Dart package name; must match the published pub package so the Native Assets -# asset id resolves to `package:livekit_uniffi/uniffi:livekit_ffi`. The package -# name is unchanged by the livekit-uniffi merge; only the library the crate -# builds is now liblivekit_ffi. -package_name = "livekit_uniffi" +# asset id resolves to `package:livekit_ffi/uniffi:livekit_ffi`. +package_name = "livekit_ffi" cdylib_name = "livekit_ffi" \ No newline at end of file From cc45089484d136d7c1556c5adf633100ce558f1a Mon Sep 17 00:00:00 2001 From: Ryan Gaus Date: Tue, 20 Oct 2026 12:20:37 +1300 Subject: [PATCH 2/2] fix(ci): let a failed feature resolve stop the Dart cdylib build `export FLAGS=$(...)` is a builtin whose own exit status is 0, so `set -e` never saw `ffi_features.py` fail. FLAGS would be empty and the build fell through to `cargo build -p livekit-ffi` with no feature flags -- the default feature set, room-apis -- quietly producing the wrong surface and publishing it to pub.dev as the Dart cdylib. Splitting the assignment from the export restores the check: a plain assignment carries the command substitution's status, so the step now aborts before `docker run`. Verified both paths: a failing resolver exits 2 without reaching the docker step, and the success path still exports `--no-default-features --features core-modules` into the container. This was the only affected call site. The other invocations here and in livekit-ffi/Makefile.toml already use a plain assignment, and cargo-make's `@shell` runner does propagate a failed command substitution (checked against cargo-make 0.37.24). Co-Authored-By: Claude Opus 5 (1M context) --- .github/workflows/uniffi-cdylib.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/uniffi-cdylib.yml b/.github/workflows/uniffi-cdylib.yml index b8458acf8..6fc53a9d4 100644 --- a/.github/workflows/uniffi-cdylib.yml +++ b/.github/workflows/uniffi-cdylib.yml @@ -119,7 +119,8 @@ jobs: BUILD_IMAGE: ${{ matrix.build_image }} run: | set -euo pipefail - export FLAGS=$(python3 .github/scripts/ffi_features.py dart) + FLAGS=$(python3 .github/scripts/ffi_features.py dart) + export FLAGS docker run --rm -e TARGET -e FLAGS -v "$PWD:/workspace" -w /workspace "$BUILD_IMAGE" bash -euo pipefail -c ' curl --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y --profile minimal --default-toolchain none export PATH="/root/.cargo/bin:$PATH"