Status Update
Comments
xa...@google.com <xa...@google.com>
sp...@google.com <sp...@google.com> #2
Information redacted by Android Beta Feedback.
sp...@google.com <sp...@google.com> #3
Thank you for reporting this issue. We have shared this with our product and engineering team and will update this issue with more information as it becomes available.
da...@google.com <da...@google.com> #4
sp...@google.com <sp...@google.com> #5
Thank you for reporting this issue. We have a fix rolling out in an upcoming release.
da...@google.com <da...@google.com> #6
sp...@google.com <sp...@google.com> #7
I'm going to leave this bug open (with decreased priority) until it's also converted into an error.
I'm pasting an excerpt of the warning below so that users who hit it and google it will find this thread if they have use cases that need to be supported.
"This version of the Android Gradle Plugin chooses the file from the app or dynamic-feature module, but this can cause unexpected behavior or errors at runtime. Future versions of the Android Gradle Plugin will throw an error in this case."
da...@google.com <da...@google.com> #8
Given that this surfaced on SO, one UX improvement might be to list the sources of the duplicates ("modules foo and bar both attempt to package libfoo.so" or something similar).
kr...@gmail.com <kr...@gmail.com> #9
As a company that develops many native components, with complex interdependencies, which are consumed by our various app teams, we have had many issues with .so file collisions in app packaging. The packagingOptions
scope in the gradle build file is of course not at all helpful in selecting the right .so files from the right sources. libc++_shared.so is just one example of this, because every module with native components contains it. We find the whole solution untenable, and have had to come up with various hacks and work arounds to make it all work together. The problem we are facing now, is that our customers who intake our various SDK modules are having similar issues with incorrect libc++_shared.so versions being included in their app packaging. And since we do not control the build files for these apps, we don't have a good answer for these customers.
sp...@google.com <sp...@google.com> #10
Re:
kr...@gmail.com <kr...@gmail.com> #11
The latter. The customer's app has another dependency using the NDK, and there is no way to control which C++ stdlib version gets packaged.
sp...@google.com <sp...@google.com> #12
danalbert@, what is the desired behavior in this scenario? To package the latest version or to throw an error unless the versions match?
kr...@gmail.com <kr...@gmail.com> #13
If you could add an action to packagingOptions
to take the latest version, I believe that would address all of our use cases. Something along the lines of pickLatestVersion
. However, is the version number a part of the binary file format? It's not in the filename.
da...@google.com <da...@google.com> #14
There's no way to know which one is newest, and selecting the latest does not guarantee that they are compatible. If you had an app using r10, selecting anything later from your package would break the app. Selecting r10 would also break the app. There's no way to ensure that two libraries with the same name are even related (I wonder how many AARs contain libnative-lib.so
because that's what's in the new project template) That's why this error (warning?) is here: these conflicts require someone actually look to see where the conflict is coming from and make a decision on how to resolve it.
The AAR you're talking about is a Java interface that just has a native implementation, right? Not a C++ interface? I'm assuming that's the case, since the mechanisms for the latter shouldn't create this problem. Assuming the former, can you restructure so that your AAR has only a single shared library that uses the static libc++, as described on
Possibly related, did anyone ever get around to making sure this warning doesn't fire if the two artifacts are actually bitwise identical? I know I'd discussed that with someone elsewhere, but apparently not here. There were probably a lot of false positives caused by that, and that's the one case where selecting one arbitrarily will be compatible.
sp...@google.com <sp...@google.com> #15
Ok, based on #14, looks like an error is the correct behavior. It's currently a warning, but the plan is to convert to an error in the future.
Possibly related, did anyone ever get around to making sure this warning doesn't fire if the two artifacts are actually bitwise identical?
You mentioned that in
The AAR you're talking about is a Java interface that just has a native implementation, right? Not a C++ interface? I'm assuming that's the case, since the mechanisms for the latter shouldn't create this problem. Assuming the former, can you restructure so that your AAR has only a single shared library that uses the static libc++, as described on
https://android.googlesource.com/platform/ndk/+/master/docs/user/middleware_vendors.md#for-java-middleware-with-jni-libraries ?
kr...@, please let me know if that workaround works for you.
da...@google.com <da...@google.com> #16
Possibly related, did anyone ever get around to making sure this warning doesn't fire if the two artifacts are actually bitwise identical?
You mentioned that in
above, and I agree that it's a good idea. I'll plan to do that before converting to an error. comment#4
Ah, missed that. Never mind :)
kr...@gmail.com <kr...@gmail.com> #17
In my experience, this already generates an error. If during app packaging, 2 native libraries with the same name exist in 2 different dependencies (AAR files), then an error will be generated about 2 files existing with the same path. It does not do a binary comparison. The only resolution available is packagingOptions.pickFirst
.
This is not sufficient for our use cases. We may have, for example, 5 different dependencies (AAR files) consumed through Maven, with a different mix of native libraries included in each. One of those dependencies needs to be designated as containing the correct version of each native library. Instead all we can do is have one picked at random using pickFirst
.
da...@google.com <da...@google.com> #18
One of those dependencies needs to be designated as containing the correct version of each native library. Instead all we can do is have one picked at random using pickFirst.
It wouldn't be picked at random, someone needs to decide which one is going to work for their app, or eliminate incompatible dependencies. I guess I don't understand how that could be done any other way (excluding the previous implementation of "choose one arbitrarily and just hope it works"). What do you have in mind?
Is
sp...@google.com <sp...@google.com> #19
In my experience, this already generates an error. If during app packaging, 2 native libraries with the same name exist in 2 different dependencies (AAR files), then an error will be generated about 2 files existing with the same path. It does not do a binary comparison. The only resolution available is packagingOptions.pickFirst.
Ah yes, that's right. It's a warning only for the case when there's a conflict between an app's native library and a dependent android library's native library.
kr...@gmail.com <kr...@gmail.com> #20
We need to be able to specify which Android archive to pick each native library from. I am hopeful that AGP 4.1 with prefab publishing will emerge as a solution that allows us to strip all native libraries out of our Android archives, and consume them using prefab (this would essentially bring the handling of native components on par with Android archives).
The actual scenario is that we have multiple different modules, each with a native component. They can be consumed in various different combinations, but there are dependencies between them at the native level. So if FooModule has a native target libfoo, and BarModule has a native target libbar, that also depends on libfoo, we end up with BarModule.aar containing both libfoo and libbar, while FooModule.aar contains libfoo. Adding both dependencies causes an error.
sp...@google.com <sp...@google.com> #21
In that example, does adding packagingOptions.exclude 'libfoo.so'
to BarModule solve the issue?
kr...@gmail.com <kr...@gmail.com> #22
It does. That means FooModule must be included as a dependency at the app level, even if it would not otherwise be necessary (maybe the Android pieces aren't required, just the native libfoo.so). That's not the end of the world, but we do end up with these rare scenarios with libc++_shared.so, where we want the most recent version, or we have a customer that's using another 3rd party dependency that's clashing with the libraries we provide.
xa...@google.com <xa...@google.com> #23
It's better to make that selection at the consuming site in case modules are consumed by different apps. Also we need this for external depenencies anyway.
We should do something like
packagingOptions {
pickFrom('libfoo.so', ':barModule') // for sub-modules
pickFrom('libfoo.so', 'groupId:artifactId:version') // for external dependencies.
}
kr...@gmail.com <kr...@gmail.com> #24
That would be awesome!
sh...@gmail.com <sh...@gmail.com> #25
sp...@google.com <sp...@google.com> #26
I filed
Description
Identically named jniLibs from different modules with different contents current cause one library to clobber the other. This is unlikely to happen for most libraries, but could be a real problem for any AAR that uses JNI, since they might use libc++_shared and then get an incompatible libc++_shared from the app.