Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Instructions: depend on mergeJniLibFolders rather than javaPreCompile #85

Open
thgoebel opened this issue Mar 1, 2022 · 4 comments
Open

Comments

@thgoebel
Copy link

thgoebel commented Mar 1, 2022

Steps to reproduce

  1. Create an Android library and use this Rust Android Gradle plugin.
  2. Add the following to your build.gradle (as per the README):
tasks.whenTaskAdded { task ->
    if ((task.name == 'javaPreCompileDebug' || task.name == 'javaPreCompileRelease')) {
        task.dependsOn 'cargoBuild'
    }
}

Actual behaviour

Case 1:
Build an Android app that directly depends on your library, e.g. via implementation project(":my-android-rust-lib").
-> The libname.so is included in the APK. 👍

Case 2:
Build just the library and publish it to some Maven repo.
-> The libname.so is missing from the AAR. 👎

Expected behaviour

The libname.so is included in the AAR.

Why this seems to be happening

The mergeJniLibFolders gradle task runs before the cargoBuild task finishes. Thus the .so are not copied over from buildDir/rustJniLibs (because they don't yet exist).
(When the library that uses the rust-android-gradle plugin is build as part of an Android app (Case 1), this race condition does not seem to occur.)

Thus this fixes it for me:

tasks.whenTaskAdded { task ->
    if ((task.name == 'mergeDebugJniLibFolders' || task.name == 'mergeReleaseJniLibFolders')) {
        task.dependsOn 'cargoBuild'
    }
}
@ncalexan
Copy link
Member

ncalexan commented Mar 1, 2022

Thank you for an excellent bug report! I've always meant to wire rust-android-gradle into the Android-Gradle plugin task graph, but I don't see a ticket for that now. I think this is probably what was happening with #43 -- but this report I understand.

I've done quite a bit of work on the automated testing harness so it's probably not too hard to write tests for generating AARs sibling to the existing tests generating APKs. And the existing test harness can target multiple Android-Gradle plugin versions too, which is needed since these specific task dependencies vary across versions.

So: thanks for uncovering this issue. I'd like to address this by trying to have the plugin automatically wire itself into the Android-Gradle plugin task graph (perhaps with an option to skip this, so that folks can do things manually should they need to) and to add tests that the behaviour works as expected for APKs and AARs. No idea when I'll be able to get to that: patches wanted! I'd also happily take a patch to README.md explaining what's going on.

@schulzch
Copy link

Since I had issues with that one and broken build caches (lib*.so not being copied after first build):

// Require cargo to be run before copying native libraries.
if ((task.name == 'mergeDebugJniLibFolders' || task.name == 'mergeReleaseJniLibFolders')) {
    task.dependsOn 'cargoBuild'
}
// Require "clean builds" to avoid issues with build caches.
if (task.name == 'assembleDebug' || task.name == 'assembleRelease')  {
    task.dependsOn 'clean'
}

Hope it helps someone else having a better day.

@ghost
Copy link

ghost commented Feb 28, 2023

Nice. Here's a slightly better iteration that uses configuration avoidance and doesn't depend on "Debug" and "Release" build variants.

tasks.withType<com.android.build.gradle.tasks.MergeSourceSetFolders>().configureEach {
    if (this.name.contains("Jni")) {
        this.dependsOn(tasks.named("cargoBuild"))
    }
}

@stan-irl
Copy link

oh jeeze i just spent like 6 hours trying to solve this. its a timing thing so the .so files were there when i published the lib from my local machine but not when the lib was published by my CI.

we really need to update the documentation.

LeanderBB pushed a commit to LeanderBB/you-have-mail that referenced this issue May 19, 2023
Fix missing copy of native libs when assembling the APK
(mozilla/rust-android-gradle#85).

Restrict supported architectures to aarch64 and x86_64.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants