Gradle DSL

The plugin adds two extensions: uniffi { } for binding generation, and cargo { } for the Rust build.

uniffi { }

uniffi {
    generateFromLibrary {                    // or generateFromUdl { udlFile = ... }
        packageName = "com.example.mylib"
    }

    formatCode = false
    addRuntime = true
    addDependencies = true
    generateBindingsForExternalCrates = false
}
Option Default Description
generateFromLibrary() — Generate bindings from the compiled library. One of the two generateFrom* calls is required. See Proc-macros and UDL.
generateFromUdl { udlFile = ... } — Generate bindings from a UDL file. udlFile is required.
packageName (in either block) — Kotlin package of the bindings. Overrides package_name from uniffi.toml, for this module's crate only. Since 1.3.0.
formatCode false Run ktlint --format over the generated bindings. ktlint must be on PATH. Problems it can't fix are reported as a warning.
addRuntime true Add ch.ubique.uniffi:runtime to commonMain. See Dependencies.
addDependencies true Add the libraries the generated code needs. See Dependencies.
generateBindingsForExternalCrates false Also generate bindings for other UniFFI crates linked into the library. See External types.

Where the generator comes from

The plugin installs the binding generator (uniffi-bindgen-kotlin-multiplatform) with cargo install the first time it is needed. You can choose the source:

Function Installs from
bindgenFromGitTag(repository, tag) a Git tag
bindgenFromGitRevision(repository, revision) a Git commit
bindgenFromGitBranch(repository, branch) the head of a Git branch, checked for updates on every build
bindgenFromGit(repository) the default branch, checked for updates on every build
bindgenFromRegistry(packageName, version) the Cargo registry
bindgenFromPath(directory) a local checkout, for developing the generator

By default the generator is installed from this repository, from the Git tag of the plugin version you use. (Up to 1.2.3, the default was the repository's default branch. Pin it with bindgenFromGitTag if you are on one of those versions.) That keeps the generator, the plugin and the runtime on the same version. Only change the source if you need an unreleased or patched generator. The generator must match the runtime version, which is always the plugin version.

The installed generator is shared by all modules of a build and kept in the root project's build/uniffi/bindgen/ directory.

cargo { }

cargo {
    packageDirectory = layout.projectDirectory
    targetDirectory = rootProject.layout.projectDirectory.dir("cargo-build")
    rustcWrapper = "sccache"
    ndkVersion = "28.1.13356709"
    androidDebugAbis.add("arm64-v8a")

    compilations.linuxArm64 {
        useCross = true
    }
}
Option Default Description
packageDirectory the project directory The directory containing Cargo.toml.
targetDirectory from cargo metadata Cargo's target directory. See Build performance.
rustcWrapper $RUSTC_WRAPPER Passed to Cargo as RUSTC_WRAPPER, for example sccache.
rustcWorkspaceWrapper $RUSTC_WORKSPACE_WRAPPER Passed to Cargo as RUSTC_WORKSPACE_WRAPPER.
ndkVersion newest installed The NDK used for Android targets. See Targets.
androidDebugAbis host ABI(s) Android ABIs built in debug builds. See Targets.
compilations.<target> { useCross = true } false Build that Rust target with cross instead of cargo.

compilations has shortcuts for iosArm64, iosX64, macosArm64, macosX64, linuxArm64, linuxX64, windowsX64, androidArm64, androidArmV7 and androidX64.

Gradle properties

Property Effect
-PreleaseBuild=true Build Rust in release mode, and for all platforms. See Targets.
-PandroidAbis=arm64-v8a,x86_64 Android ABIs for debug builds, if androidDebugAbis is not set.

Tasks

Task Does
buildBindings Generate the Kotlin bindings into build/uniffi/bindings/. Runs on IDE sync too.
installBindgen Install the binding generator.
cargoBuild<RustTarget><Debug\|Release> Build the crate for one Rust target, e.g. cargoBuildAarch64AppleDarwinDebug.
buildLibraryForBindings Build the host library the bindings are generated from.

You don't normally run these yourself. The Kotlin compile tasks depend on them.