uniffi-rs icon indicating copy to clipboard operation
uniffi-rs copied to clipboard

multi-arch bindgen guarantees

Open gtrak opened this issue 6 months ago • 1 comments

I'm not sure if I'm relying on behavior that is simply not guaranteed, or could break at an unknown time in practice, just curious if there's anything I missed in the docs or elsewhere.

I have a CI pipeline that builds a multi-os/arch jar with uniffi bindings, from a linux-x86-64 host.

I use cargo-zigbuild to package and compile different variations of the native library into a jar, for darwin-aarch64, and linux-x86-64/aarch64, maybe more targets like windows someday.

When I'm generating the kotlin bindings with uniffi-bindgen, I have to specify a single cdylib, which happens to be the build host's own target. I'm using proc-macros, so I don't have a UDL file.

What I'm wondering is if the bindings generation could ever change depending on the OS/arch, or is explicitly guaranteed to be the same no matter what variation of compiled library is passed into uniffi-bindgen, or if I need to regenerate the bindings per target architecture and OS.

In my initial testing, I had no issue using the osx dylib with bindings generated from a linux-x86-64 build box.

The bindgen gradle step looks like this:

val os = OperatingSystem.current()
val libExt = if (os.isMacOsX()) "dylib" else "so"

tasks.register("generateUniFFIBindings") {
    dependsOn("buildRust")
    doLast {
        exec {
            workingDir = rustRoot
            commandLine(
                // Generate from the build box's architecture, could be mac if local
                "target/release/uniffi-bindgen", "generate",
                "--language", "kotlin",
                "--library", "${rustRoot}/target/release/mylib.${libExt}",
                "--out-dir", "${projectDir}/src/generated/kotlin"
            )
        }
    }
}

And the packaging like this:

tasks.shadowJar {
   ...
    // matches getNativeLibraryResourcePrefix
    // https://github.com/java-native-access/jna/tree/master/src/com/sun/jna/Platform.java#L314
    into("linux-x86-64") {
        from("${rustRoot}/target/x86_64-unknown-linux-gnu/release/mylib.so")
    }
    into("linux-aarch64") {
        from("${rustRoot}/target/aarch64-unknown-linux-gnu/release/mylib.so")
    }
    into("darwin-aarch64") {
        from("${rustRoot}/target/aarch64-apple-darwin/release/mylib.dylib")
    }
}

Thanks for this awesome project!

gtrak avatar Apr 18 '25 18:04 gtrak