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

Updates to fix android builds failing in Expo #676

Closed
wants to merge 3 commits into from

Conversation

haibert
Copy link
Sponsor

@haibert haibert commented Dec 24, 2021

What

This PR applies all the changes from the following comment which did fix the android build issue when using expo custom-dev-client.

Changes

  • in /android/CMakeLists.txt added ${NODE_MODULES_DIR}/react-native/ReactCommon/jsi/jsi/jsi.cpp in the "add_library" list
  • in /android/CMakeLists.txt removed ${JSI_LIB} from the target_link_libraries list
  • in /android/build.gradle added the following excludes to the packagingOptions "/libreactnativejni.so", "/libfolly_json.so", "/libreanimated.so", "/libjscexecutor.so"
  • in grade.properties changed VisionCamera_compileSdkVersion from 31 to 30

⚠️NOTE⚠️
Even with these changes applied the user will need to use the following config plugin (Courtesy of AdamMercy) to get a successful build.

const { withProjectBuildGradle } = require('@expo/config-plugins')

const setCompileSdkVersion = (buildGradle, sdkVersion) => {
    const regexpCompileSdkVersion = /\bcompileSdkVersion\s*=\s*(\d+)/
    const match = buildGradle.match(regexpCompileSdkVersion)

    if (match) {
        const existingVersion = parseInt(match[1], 10)

        if (existingVersion < sdkVersion) {
            buildGradle = buildGradle.replace(
                /\bcompileSdkVersion\s*=\s*\d+/,
                `compileSdkVersion = ${sdkVersion}`
            )
        } else {
            throw new Error(`minSdkVersion is already >= ${sdkVersion}`)
        }
    }

    return buildGradle
}

module.exports = (config, sdkVersion) => {
    return withProjectBuildGradle(config, (config) => {
        if (config.modResults.language === 'groovy') {
            config.modResults.contents = setCompileSdkVersion(
                config.modResults.contents,
                sdkVersion
            )
        } else {
            throw new Error(
                "Can't set minSdkVersion in the project build.gradle, because it's not groovy"
            )
        }
        return config
    })
}

Then inside of app.json

//---------------IN APP.JSON-----------------

"plugins": [
            "react-native-vision-camera",
            ["./withCompileSdkVersion", 31]
        ]

//---------------IN APP.JSON-----------------

Tested on

* Samsung Galaxy Note8

Related issues

* Closes #546 

Copy link
Owner

@mrousavy mrousavy left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@haibert thank you for the PR bro! 🙏

While that makes it build for Expo (RN 0.64?), it has some problems in current RN versions. We need to make it conditional, fall back to compiling jsi.cpp if RN version is older. Then it works for both.

@@ -22,6 +22,7 @@ add_library(
src/main/cpp/java-bindings/JFrameProcessorPlugin.cpp
src/main/cpp/java-bindings/JImageProxy.cpp
src/main/cpp/java-bindings/JHashMap.cpp
${NODE_MODULES_DIR}/react-native/ReactCommon/jsi/jsi/jsi.cpp
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be avoided if possible. Does it really not build if that line is removed? If not, then please make this conditional (if + set), so it is not compiled in RN versions that support the JSI_LIB library below.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

aka: On RN 0.64 and below, compile jsi.cpp here. On RN 0.65 and above, do NOT compile jsi.cpp here, but find the JSI_LIB below.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the reason for that is, that on RN 0.65 and above, jsi.cpp is compiled multiple times - aka we have duplicate symbols. This is a problem in C++, since JSI now exists more than once. My jsi::JSError for example is not the same as jsi::JSError in React Native, therefore the app hard-crashes. So we need to make that conditional. Check out Reanimated codebase on how they do it

Comment on lines -90 to -95
find_library(
JSI_LIB
jsi
PATHS ${LIBRN_DIR}
NO_CMAKE_FIND_ROOT_PATH
)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

conditional

@@ -125,7 +120,6 @@ message(WARNING "VisionCamera linking: FOR_HERMES=${FOR_HERMES}")
target_link_libraries(
${PACKAGE_NAME}
${LOG_LIB}
${JSI_LIB}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

conditional

@hirbod
Copy link
Contributor

hirbod commented Jan 2, 2022

And afaik this will break Hermes, right?

@mrousavy
Copy link
Owner

mrousavy commented Jan 2, 2022

Why would it break Hermes?

@hirbod
Copy link
Contributor

hirbod commented Jan 2, 2022

@mrousavy that was the latest info I got from @haibert regarding this comment.
#546 (comment)

Haven't verified it yet

@mrousavy
Copy link
Owner

mrousavy commented Jan 2, 2022

Hey! @haibert @hirbod can you test if the latest VisionCamera version now successfully builds and runs for you? I finally had the time to investigate those boring build issues, hope everything's resolved for you guys now 🙏

@hirbod
Copy link
Contributor

hirbod commented Jan 2, 2022

@mrousavy will test this in 30 minutes and report back

@hirbod
Copy link
Contributor

hirbod commented Jan 2, 2022

@mrousavy I need to dig around this issue first, looks like monorepos aren't still fully supported

FAILURE: Build failed with an exception.

* Where:
Build file '/myapp/packages/expo/node_modules/react-native-vision-camera/android/build.gradle' line: 8

* What went wrong:
A problem occurred evaluating project ':react-native-vision-camera'.
> /myapp/packages/expo/node_modules/react-native-vision-camera/node_modules/react-native/ReactAndroid/gradle.properties (No such file or directory)

@hirbod
Copy link
Contributor

hirbod commented Jan 2, 2022

@mrousavy it is not working unfortunately. (installed 2.11.0)

  1. I patched the monorepo path for now, which got rid of the first issue, but then I had to use a config-plugin to bump compileSdkVersion from 30 to 31, also not a big deal, but still a step.

  2. After that, I get tons of this here. Gosh I hate android from the bottom of my heart

5): Class 'kotlin.Unit' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.6.0, expected version is 1.4.0.
The class is loaded from /Users/hirbod/.gradle/caches/transforms-3/f824ddc606dcba394bb492d21c1ac821/transformed/jetified-kotlin-stdlib-1.6.0.jar!/kotlin/Unit.class
e: /myapp/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/CameraViewModule.kt: (82, 20): Class 'kotlin.coroutines.CoroutineContext' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.6.0, expected version is 1.4.0.
The class is loaded from /Users/hirbod/.gradle/caches/transforms-3/f824ddc606dcba394bb492d21c1ac821/transformed/jetified-kotlin-stdlib-1.6.0.jar!/kotlin/coroutines/CoroutineContext.class
e: /myapp/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/CameraViewModule.kt: (83, 7): Class 'kotlin.Unit' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.6.0, expected version is 1.4.0.
The class is loaded from /Users/hirbod/.gradle/caches/transforms-3/f824ddc606dcba394bb492d21c1ac821/transformed/jetified-kotlin-stdlib-1.6.0.jar!/kotlin/Unit.class
e: /myapp/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/CameraViewModule.kt: (90, 4): Class 'kotlin.Suppress' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.6.0, expected version is 1.4.0.
The class is loaded from /Users/hirbod/.gradle/caches/transforms-3/f824ddc606dcba394bb492d21c1ac821/transformed/jetified-kotlin-stdlib-1.6.0.jar!/kotlin/Suppress.class
e: /myapp/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/CameraViewModule.kt: (93, 20): Class 'kotlin.coroutines.CoroutineContext' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.6.0, expected version is 1.4.0.
The class is loaded from /Users/hirbod/.gradle/caches/transforms-3/f824ddc606dcba394bb492d21c1ac821/transformed/jetified-kotlin-stdlib-1.6.0.jar!/kotlin/coroutines/CoroutineContext.class
e: /myapp/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/CameraViewModule.kt: (94, 7): Class 'kotlin.Unit' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.6.0, expected version is 1.4.0.
The class is loaded from /Users/hirbod/.gradle/caches/transforms-3/f824ddc606dcba394bb492d21c1ac821/transformed/jetified-kotlin-stdlib-1.6.0.jar!/kotlin/Unit.class
e: /myapp/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/CameraViewModule.kt: (104, 20): Class 'kotlin.coroutines.CoroutineContext' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.6.0, expected version is 1.4.0.
The class is loaded from /Users/hirbod/.gradle/caches/transforms-3/f824ddc606dcba394bb492d21c1ac821/transformed/jetified-kotlin-stdlib-1.6.0.jar!/kotlin/coroutines/CoroutineContext.class
e: /myapp/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/CameraViewModule.kt: (106, 7): Class 'kotlin.Unit' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.6.0, expected version is 1.4.0.
The class is loaded from /Users/hirbod/.gradle/caches/transforms-3/f824ddc606dcba394bb492d21c1ac821/transformed/jetified-kotlin-stdlib-1.6.0.jar!/kotlin/Unit.class
e: /myapp/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/CameraViewModule.kt: (107, 14): Class 'kotlin.Unit' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.6.0, expected version is 1.4.0.
The class is loaded from /Users/hirbod/.gradle/caches/transforms-3/f824ddc606dcba394bb492d21c1ac821/transformed/jetified-kotlin-stdlib-1.6.0.jar!/kotlin/Unit.class
e: /myapp/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/CameraViewModule.kt: (110, 9): Class 'kotlin.Unit' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.6.0, expected version is 1.4.0.
The class is loaded from /Users/hirbod/.gradle/caches/transforms-3/f824ddc606dcba394bb492d21c1ac821/transformed/jetified-kotlin-stdlib-1.6.0.jar!/kotlin/Unit.class
e: /myapp/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/CameraViewModule.kt: (113, 9): Class 'kotlin.Unit' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.6.0, expected version is 1.4.0.
The class is loaded from /Users/hirbod/.gradle/caches/transforms-3/f824ddc606dcba394bb492d21c1ac821/transformed/jetified-kotlin-stdlib-1.6.0.jar!/kotlin/Unit.class
e: /myapp/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/CameraViewModule.kt: (120, 5): Class 'kotlin.Unit' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.6.0, expected version is 1.4.0.
The class is loaded from /Users/hirbod/.gradle/caches/transforms-3/f824ddc606dcba394bb492d21c1ac821/transformed/jetified-kotlin-stdlib-1.6.0.jar!/kotlin/Unit.class
e: /myapp/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/CameraViewModule.kt: (122, 12): Class 'kotlin.Unit' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.6.0, expected version is 1.4.0.
The class is loaded from /Users/hirbod/.gradle/caches/transforms-3/f824ddc606dcba394bb492d21c1ac821/transformed/jetified-kotlin-stdlib-1.6.0.jar!/kotlin/Unit.class
e: /myapp/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/CameraViewModule.kt: (129, 20): Class 'kotlin.coroutines.CoroutineContext' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.6.0, expected version is 1.4.0.
The class is loaded from /Users/hirbod/.gradle/caches/transforms-3/f824ddc606dcba394bb492d21c1ac821/transformed/jetified-kotlin-stdlib-1.6.0.jar!/kotlin/coroutines/CoroutineContext.class
e: /myapp/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/CameraViewModule.kt: (130, 7): Class 'kotlin.Unit' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.6.0, expected version is 1.4.0.
The class is loaded from /Users/hirbod/.gradle/caches/transforms-3/f824ddc606dcba394bb492d21c1ac821/transformed/jetified-kotlin-stdlib-1.6.0.jar!/kotlin/Unit.class
e: /myapp/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/CameraViewModule.kt: (132, 14): Class 'kotlin.Unit' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.6.0, expected version is 1.4.0.
The class is loaded from /Users/hirbod/.gradle/caches/transforms-3/f824ddc606dcba394bb492d21c1ac821/transformed/jetified-kotlin-stdlib-1.6.0.jar!/kotlin/Unit.class
e: /myapp/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/CameraViewModule.kt: (143, 20): Class 'kotlin.coroutines.CoroutineContext' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.6.0, expected version is 1.4.0.
The class is loaded from /Users/hirbod/.gradle/caches/transforms-3/f824ddc606dcba394bb492d21c1ac821/transformed/jetified-kotlin-stdlib-1.6.0.jar!/kotlin/coroutines/CoroutineContext.class
e: /myapp/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/CameraViewModule.kt: (144, 7): Class 'kotlin.Unit' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.6.0, expected version is 1.4.0.
The class is loaded from /Users/hirbod/.gradle/caches/transforms-3/f824ddc606dcba394bb492d21c1ac821/transformed/jetified-kotlin-stdlib-1.6.0.jar!/kotlin/Unit.class
e: /myapp/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/CameraViewModule.kt: (154, 30): Unresolved reference: forEach
e: /myapp/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/CameraViewModule.kt: (162, 26): Unresolved reference: contains
e: /myapp/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/CameraViewModule.kt: (170, 26): Unresolved reference: contains
e: /myapp/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/CameraViewModule.kt: (171, 49): Unresolved reference: contains
e: /myapp/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/CameraViewModule.kt: (191, 15): Class 'kotlin.Unit' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.6.0, expected version is 1.4.0.
The class is loaded from /Users/hirbod/.gradle/caches/transforms-3/f824ddc606dcba394bb492d21c1ac821/transformed/jetified-kotlin-stdlib-1.6.0.jar!/kotlin/Unit.class
e: /myapp/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/CameraViewModule.kt: (192, 15): Class 'kotlin.Unit' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.6.0, expected version is 1.4.0.
The class is loaded from /Users/hirbod/.gradle/caches/transforms-3/f824ddc606dcba394bb492d21c1ac821/transformed/jetified-kotlin-stdlib-1.6.0.jar!/kotlin/Unit.class
e: /myapp/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/CameraViewModule.kt: (193, 15): Class 'kotlin.Unit' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.6.0, expected version is 1.4.0.
The class is loaded from /Users/hirbod/.gradle/caches/transforms-3/f824ddc606dcba394bb492d21c1ac821/transformed/jetified-kotlin-stdlib-1.6.0.jar!/kotlin/Unit.class
e: /myapp/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/CameraViewModule.kt: (194, 15): Class 'kotlin.Unit' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.6.0, expected version is 1.4.0.
The class is loaded from /Users/hirbod/.gradle/caches/transforms-3/f824ddc606dcba394bb492d21c1ac821/transformed/jetified-kotlin-stdlib-1.6.0.jar!/kotlin/Unit.class
e: /myapp/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/CameraViewModule.kt: (195, 15): Class 'kotlin.Unit' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.6.0, expected version is 1.4.0.
The class is loaded from /Users/hirbod/.gradle/caches/transforms-3/f824ddc606dcba394bb492d21c1ac821/transformed/jetified-kotlin-stdlib-1.6.0.jar!/kotlin/Unit.class
e: /myapp/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/CameraViewModule.kt: (196, 15): Class 'kotlin.Unit' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.6.0, expected version is 1.4.0.
The class is loaded from /Users/hirbod/.gradle/caches/transforms-3/f824ddc606dcba394bb492d21c1ac821/transformed/jetified-kotlin-stdlib-1.6.0.jar!/kotlin/Unit.class
e: /myapp/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/CameraViewModule.kt: (197, 15): Class 'kotlin.Unit' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.6.0, expected version is 1.4.0.
The class is loaded from /Users/hirbod/.gradle/caches/transforms-3/f824ddc606dcba394bb492d21c1ac821/transformed/jetified-kotlin-stdlib-1.6.0.jar!/kotlin/Unit.class
e: /myapp/node_modules/react-native-vision-camera/android/src/main/java/com/mrousavy/camera/CameraViewModule.kt: (198, 15): Class 'kotlin.Unit' was compiled with an incompatible version of Kotlin. The binary version of its metadata is 1.6.0, expected version is 1.4.0.

I truncated the output, since its just complaining about the kotlin versions.

@hirbod
Copy link
Contributor

hirbod commented Jan 2, 2022

@mrousavy alright, after some digging, I found that I had a config-plugin, which inserted following:

    dependencies {
        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:1.4.10"
    }

I had to patch the value from 1.4.10 to 1.5.10 (because 1.6.0 would break expo-dev-launcher) and it looked like that everything will finally compile, but ended up with this error in the last 1% :D

Execution failed for task ':app:mergeDebugNativeLibs'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.Workers$ActionFacade
   > More than one file was found with OS independent path 'lib/x86/libc++_shared.so'. If you are using jniLibs and CMake IMPORTED targets, see https://developer.android.com/studio/preview/features#automatic_packaging_of_prebuilt_dependencies_used_by_cmake

@mrousavy
Copy link
Owner

mrousavy commented Jan 2, 2022

Okay thanks for the detailed feedback @hirbod!

  1. Ok for monorepo I will need to figure the node_modules path out clearly.
  2. compileSdkVersion still needs to be 31, I don't really want to add that to my config plugin tho, don't think that should be handled on my side...
  3. Kotlin version you already resolved
  4. Duplicate lib: I'll take a look

@mrousavy
Copy link
Owner

mrousavy commented Jan 2, 2022

You can also fix that duplicate lib error yourself in your build.gradle btw :)
That's the recommended approach anyways, a pickFirst is always better than an exclude!

@hirbod
Copy link
Contributor

hirbod commented Jan 2, 2022

@mrousavy I agree with everything you said. We should just state a little info for the expo users, that they might need a config-plugin which bumps 30 to 31 and add some docs for it.

Regarding pickFirst etc: not exactly sure where to do that + it has to be patched in build.gradle, which would need a config-plugin again. Because that excludes = ["**/libc++_shared.so", is already in your build.gradle

@haibert
Copy link
Sponsor Author

haibert commented Jan 2, 2022

@mrousavy Hi Marc! You are the man!
I had a failed build with the following error

[stderr] FAILURE: Build failed with an exception.
[stderr] * Where:
[stderr] Build file '/root/workingdir/build/node_modules/react-native-vision-camera/android/build.gradle' line: 8
[stderr] * What went wrong:
[stderr] A problem occurred evaluating project ':react-native-vision-camera'.
[stderr] > /root/workingdir/build/node_modules/react-native-vision-camera/node_modules/react-native/ReactAndroid/gradle.properties (No such file or directory)
[stderr] * Try:
[stderr] Run with --stacktrace option to get the stack trace. Run with --info or --debug option to get more log output. Run with --scan to get full insights.
[stderr] * Get more help at https://help.gradle.org
[stderr] BUILD FAILED in 2m 9s

@hirbod
Copy link
Contributor

hirbod commented Jan 2, 2022

@haibert are using a monorepo like me? I had to patch-package like 6 paths to get rid of this. (node_modules/rnvc/android/build.gradle)

But the first error also occured on the first install, because the gradle just got updated after the 2nd build

@mrousavy
Copy link
Owner

mrousavy commented Jan 2, 2022

where's your node_modules?

@haibert
Copy link
Sponsor Author

haibert commented Jan 2, 2022

@mrousavy
1

its in the root of my project directory

@hirbod
Copy link
Contributor

hirbod commented Jan 2, 2022

@haibert just try expo prebuild --clean. As said, line 8 was missing for me on the first try and just got updated after the second. I had to dig further though, since I am using a monorepo and all the hardcoded paths have been wrong for me.

@haibert
Copy link
Sponsor Author

haibert commented Jan 2, 2022

@hirbod Hi Hirbod,

I am using eas build, I run the following command "eas build --profile development --platform android"
I dont think theres a way to do that with eas?

@hirbod
Copy link
Contributor

hirbod commented Jan 2, 2022

@haibert ok, I see. Well, I will end up there eventually, when my dev process is done and I need to create a release.

@mrousavy I monkey patched my android/app/build.gradle and added every duplicate that was being reported like so:

    packagingOptions {
        excludes = ['lib/x86/libc++_shared.so', 'lib/arm64-v8a/libc++_shared.so', 'lib/x86_64/libc++_shared.so', 'lib/armeabi-v7a/libc++_shared.so']
        exclude "META-INF/**"
    }

My app finally was building and the development client booted, but ended up like so:

Bildschirmfoto 2022-01-02 um 21 33 21

@haibert
Copy link
Sponsor Author

haibert commented Jan 2, 2022

@hirbod @mrousavy prebuilding didnt give any errors. I guess the error is with when you use eas build to create the a build from the cloud? maybe the nodemodules isnt in the root directory when you send your project to the cloud im guessing.. Have you tried to do a release build Hirbod?

@hirbod
Copy link
Contributor

hirbod commented Jan 2, 2022

@mrousavy alright, while I do not consider this a solution, FOR NOW, my app is building (but still crashing due to reanimated and dev tools).

I had to patch it like so:

    packagingOptions {
        pickFirst 'lib/x86/libc++_shared.so'
        pickFirst 'lib/arm64-v8a/libc++_shared.so'
        pickFirst 'lib/x86_64/libc++_shared.so'
        pickFirst 'lib/armeabi-v7a/libc++_shared.so'
    }

@haibert no, I never used "eas" cloud stuff so far.

EDIT: IT IS FINALLY WORKING. As said, with the patch, but I have a running android app, cant believe it!

@mrousavy
Copy link
Owner

mrousavy commented Jan 3, 2022

@hirbod seems like you figured it out already.

exclude actually drops the libraries and doesn't link them. pickFirst uses the first of those available. So with your first "monkeypatch" you stole a required library from your app 😄

The pickFirst approach seems reasonable, after all this is because React Native doesn't offer good support for native library consumers (prefabs). I also have this in my regular React Native app. It works because the libc++ library version is the same anyways.

So in conclusion, what needs to be done is:

  1. Fix the monorepo path finding for node_modules.
  2. Wait until React Native ships their native libraries as prefabs, then you don't need pickFirst anymore.

@hirbod
Copy link
Contributor

hirbod commented Jan 3, 2022

Hi Marc,

thanks for the clarification. So I would say we need to provide / update the config plug-in and add the above to /android/app/build.gradle

This could be a workaround. Shall we open an issue upstream or is this something already known?

Edit:
@mrousavy looks like someone built a approach here:
#545 (comment)

@hirbod hirbod mentioned this pull request Jan 3, 2022
@haibert
Copy link
Sponsor Author

haibert commented Jan 3, 2022

@mrousavy Hi Marc,

So 2.11.1 got rid of the monorepo issue. I had to use a plugin to set the compileSdkVersion to 31, but I got the build error bellow

FAILURE: Build failed with an exception.
[stderr] * What went wrong:
[stderr] Execution failed for task ':app:mergeDebugNativeLibs'.
[stderr] > A failure occurred while executing com.android.build.gradle.internal.tasks.Workers$ActionFacade
[stderr]    > More than one file was found with OS independent path 'lib/x86/libhermes.so'. If you are using jniLibs and CMake IMPORTED targets, see https://developer.android.com/studio/preview/features#automatic_packaging_of_prebuilt_dependencies_used_by_cmake

@hirbod
Copy link
Contributor

hirbod commented Jan 3, 2022

@haibert check out my PR
#708

    [
      'react-native-vision-camera',
      {
        enableMicrophonePermission: true,
        disableFrameProcessors: true,
        dangerouslyHandleAndroidSharedLibrary: true
      }
    ],

I've added two new options for android (disable frame proceccsors, if you don't need them + fixing the sharedlibrary issue that you also encountered).

Thanks for your report, this helped me to change the glob pattern.

@haibert
Copy link
Sponsor Author

haibert commented Jan 3, 2022

@hirbod awesome! Thank you I will try this out!

@hirbod
Copy link
Contributor

hirbod commented Jan 4, 2022

@haibert my PR will now be able to disable frame processors also for iOS.

@hirbod
Copy link
Contributor

hirbod commented Jan 14, 2022

This PR is obsolete.

Since my dangerouslyHandleAndroidSharedLibrary prop was removed, people will most likely encounter issues with expo-dev-client.

So it is necessary to use the minSdkVersion plugin (bump to 31) and the pickFirst config plugin. (see below)

const {
    withAppBuildGradle
} = require('@expo/config-plugins')

const addPickFirst = (buildGradle, paths) => {
    const regexpPackagingOptions = /\bpackagingOptions\s*{[^}]*}/
    const packagingOptionsMatch = buildGradle.match(regexpPackagingOptions)

    const bodyLines = []

    paths.forEach((path) => bodyLines.push(`pickFirst '${path}'`))

    const body = bodyLines.join('\n        ')

    if (packagingOptionsMatch) {
        console.warn(
            'WARN: withPickFirst: Replacing packagingOptions in app build.gradle'
        )

        return buildGradle.replace(
            regexpPackagingOptions,
            `packagingOptions {
        ${body}
       }
      `
        )
    }

    const regexpAndroid = /\nandroid\s*{/
    const androidMatch = buildGradle.match(regexpAndroid)

    if (androidMatch) {
        return buildGradle.replace(
            regexpAndroid,
            `
android {
    packagingOptions {
        ${body}
    }
     `
        )
    }

    throw new Error('withPickFirst: Could not find where to add packagingOptions')
}

module.exports = (config, paths) => {
    if (!paths) {
        throw new Error('withPickFirst: No paths specified!')
    }

    return withAppBuildGradle(config, (config) => {
        if (config.modResults.language === 'groovy') {
            config.modResults.contents = addPickFirst(
                config.modResults.contents,
                paths
            )
        } else {
            throw new Error(
                "withPickFirst: Can't add pickFirst(s) because app build.grandle is not groovy"
            )
        }
        return config
    })
}

and install it like this

    ['./plugins/withPickFirst', ['lib/x86/libc++_shared.so', 'lib/x86_64/libc++_shared.so', 'lib/armeabi-v7a/libc++_shared.so', 'lib/arm64-v8a/libc++_shared.so']],

@mrousavy
Copy link
Owner

Thanks for the explanation @hirbod!

@mrousavy mrousavy closed this Jan 14, 2022
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

Successfully merging this pull request may close these issues.

None yet

3 participants