Git Product home page Git Product logo

Comments (12)

cortinico avatar cortinico commented on September 2, 2024 1

Piggybacking here as we're facing the same exact issue on React Native. We're looking into consume fbjni as a Prefab:

I think the best approach here would be to ship 2 distributions of fbjni, one with libc++_shared.so and one without (that's what Hermes is doing). As an alternative, just remove libc++_shared.so from fbjni entirely as suggested by the Android documentation:
https://developer.android.com/ndk/guides/cpp-support#shared_runtimes

Caution: JNI libraries distributed with Java AARs must not use the shared runtime to avoid conflicting with other libraries and the app. The warnings below still apply. See the documentation for Middleware Vendors for more information.

We're currently blocked on React Native with a:

> A failure occurred while executing com.android.build.gradle.internal.tasks.MergeNativeLibsTask$MergeNativeLibsTaskWorkAction
   > 2 files found with path 'lib/arm64-v8a/libc++_shared.so' from inputs:
      - /root/.gradle/caches/transforms-3/94fdb9ae737c1ffb0e2b5a7d92619e93/transformed/jetified-react-native-1000.0.0-d1bc3bfd2/jni/arm64-v8a/libc++_shared.so
      - /root/.gradle/caches/transforms-3/e97ae185b4d1b38cfd833e7ebc155a69/transformed/jetified-fbjni-0.2.2/jni/arm64-v8a/libc++_shared.so
     If you are using jniLibs and CMake IMPORTED targets, see
     https://developer.android.com/r/tools/jniLibs-vs-imported-targets

ref: https://app.circleci.com/pipelines/github/facebook/react-native/12400/workflows/eb260b13-6ae7-4927-a915-4be5c0643027/jobs/239232

And we have to resort to the current non-prefab approach, which relies on unbundling the libraries manually (the one described in this repo docs) which is essentially equivalent to drop the libc++_shared.so library provided in the artifact.

from fbjni.

cpsauer avatar cpsauer commented on September 2, 2024 1

@cortinico I think they mean something slightly different by that quote, especially given the linked middleware guide. (For all others, it's super worth a read! It succinctly answers the "whys" above. And it seems like we might be conflating bundling the shared C++ standard library with linking against it.)

To have fbjni not link, use, and need the shared C++ standard library, we'd want to add an option to statically link fbjni into apps or libraries that use it. That could be done by distributing static archives (or just compiling the source) and giving the option to set the shared library name on the Java side (as mentioned in #62 (comment)). We might also want to provide a linker script to help people preserve the Java->C++ JNI entry points. (See https://developer.android.com/ndk/guides/middleware-vendors#using_the_stl). It seems like the Android guides would recommend this for most use cases, but fbjni isn't currently distributed this way, unfortunately.

[Otherwise, fbjni has to dynamically link against the C++ standard library, since the standard library is (unfortunately) part of its interface, as per the middleware guide. (Another (probably worse) fix would be moving to a no-STL interface, as the guide notes.) Hopefully that answers @henryzx's initial "why" question, above.]

All that said, it seems like maybe the app and using-library cases could be solved by just dynamically linking against (the same) C++ standard library as fbjni, bundled or not? The real pain comes when using two libraries that want different standard libraries.

from fbjni.

atsushieno avatar atsushieno commented on September 2, 2024 1

What I really meant is that libcxx-provider would eliminate the last issue that prevents migration to "Prefab packaging without libcxx_shared.so" model. (Thus my comment primarily targets FBJNI developers, not its consumers.)

libcxx-provider is not suitable if the app project builds its own C++ code, given that the dependencies do not bundle libc++_shared.so. You're right on that it will only result in bringing extraneous libc++_shared.so on the table.
It is useful when no deps bundle libc++_shared.so AND there is no externalNativeBuild in the app either (which then results in UnsatisfiedLinkError due to missing libc++_shared.so). For such a case libcxx-provider is useful.

To my understanding the UnsatisfiedLinkError is the only problematic case that prevents Prefab and "do not bundle STL" approach. Old prefabs did not mix with non-prefab AARs, but now they do, if I understand correctly.

from fbjni.

bogerchan avatar bogerchan commented on September 2, 2024

+1

from fbjni.

ussernamenikita avatar ussernamenikita commented on September 2, 2024

+1

from fbjni.

passy avatar passy commented on September 2, 2024

I've played around with -DANDROID_STL=c++_static and that's not compatible with our other projects, like Flipper which builds further shared libraries based on it.

I'm seeing errors like this:

prefabandroid.armeabi-v7a: Library is a shared library with a statically linked STL and cannot be used with any library using the STL

Unless we find a solution for that, we won't be able to change the default for our distribution.

from fbjni.

cpsauer avatar cpsauer commented on September 2, 2024

Related to #62

from fbjni.

cortinico avatar cortinico commented on September 2, 2024

Following up here @cpsauer

All that said, it seems like maybe the app and using-library cases could be solved by just dynamically linking against (the same) C++ standard library as fbjni, bundled or not?

According to this answer android/ndk#1283 (comment) from the folks on the NDK, the recommended approach is to use libc++_shared.so (as FBJNI is doing right now). So yeah, the current bundling seems to be the preferred one.

The libc++_shared.so shipped with fbjni.aar conflicts with our app's.

To solve @henryzx problem, he could technically use a pickFirst{} block and let AGP decide which libc++_shared.so to pick. The problem is that by doing so you don't allow a developer to pick the libc++ from the library they wish (as AGP will decide for them).

AGP will prioritize libc++_shared.so from the app, if it exists (it should print a warning). But if you import two libraries (say React Native and FBJNI) which both imports libc++_shared.so then you're forced to use a pickFirst{}.

The solution I was suggesting was to publish 2 version/flavors of FBJNI (one with the bundled libc++_shared.so and one without) to overcome this.

from fbjni.

cpsauer avatar cpsauer commented on September 2, 2024

πŸ‘πŸ» I suppose more generally, is it clear that FBJNI should be bundling libc++_shared at all, as opposed to just requiring it?

from fbjni.

cortinico avatar cortinico commented on September 2, 2024

πŸ‘πŸ» I suppose more generally, is it clear that FBJNI should be bundling libc++_shared at all, as opposed to just requiring it?

could you clarify? As I'm not sure if you missed a not in your sentence.

To reiterate: I believe FBJNI could bundle libc++_shared.so, but should also offer a way to be consumed without.

from fbjni.

atsushieno avatar atsushieno commented on September 2, 2024

Back in June I created this library and published some AARs that only contain libc++_shared.so. Does this look helpful? https://github.com/atsushieno/libcxx-provider/

from fbjni.

cortinico avatar cortinico commented on September 2, 2024

Back in June I created this library and published some AARs that only contain libc++_shared.so. Does this look helpful? https://github.com/atsushieno/libcxx-provider/

Sadly not, as we need to don't have libc++_shared.so bundled at all in any dependency modulo the App (or React Native). Adding libcxx provider will add yet another libc++_shared.so

from fbjni.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    πŸ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. πŸ“ŠπŸ“ˆπŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❀️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.