libreactnativejni.so在64位android ndk(linux)

时间:2018-04-24 15:23:56

标签: android-ndk react-native-android

编辑:我设法构建了libreactnativejni.so的x86_64版本(请参阅我的回答)。然而,它并没有解决我的问题。

总结我在这里学到的是:

你无法测试在Linux上使用本机库的android组件,因为" libandroid.so" (核心android lib),对Linux来说并不存在。

原始问题:

我的目标是使用类似于RootViewTest.java的PowerMockito在我的Linux机器上运行测试。 不确定react-native团队如何设法运行此测试,但根据我的经验,无法加载jni库Arguments.createArray,无法模拟reactnativejni。原因是Arguments.createArray()调用WritableNativeArray,静态初始值设定项ReactBridge.staticInit()调用SoLoader.loadLibrary("reactnativejni")

所以我认为我没有其他选择,但compile this reactnativejni shared library用于linux,使用64位android-ndk-r10e

我设法加载这个jni lib并使用以下代码测试我的代码:

ndkDir=$(pwd)/react-ndk/all/x86 \
  JAVA_OPTS="-Djava.library.path=\".:$ndkDir\"" \
  LD_LIBRARY_PATH="$ndkDir:$LD_LIBRARY_PATH" ./gradlew app:test

但测试失败了:

libreactnativejni.so: wrong ELF class: ELFCLASS32 (Possible cause: architecture word width mismatch)

使用objdump检查平台:

objdump -s --section .comment libreactnativejni.so

libreactnativejni.so:     file format elf32-i386

我的问题是64位ndk如何产生32位库以及如何强制产生64位。

库构建脚本编写为gradle脚本:

https://github.com/facebook/react-native/blob/26684cf3adf4094eb6c405d345a75bf8c7c0bf88/ReactAndroid/build.gradle#L199

2 个答案:

答案 0 :(得分:1)

ReactAndroid显式requests 32位目标。如果您愿意,可以将此行替换为

APP_ABI := all

答案 1 :(得分:0)

我将回答我自己的问题(感谢Alex获得APP_ABI的好评)。要编译reactnativejni的x86_64变体,请按照以下步骤操作:

  1. 将APP_ABI更新为APP_ABI := armeabi-v7a x86_64 x86
  2. 中的ReactAndroid/src/main/jni/Application.ml

    下一个问题是依赖jsc-android,它不是为X86_64目标构建的。还有替代jsc-android-buildscripts,它也是为X86_64构建的。

    1. 直接从aar中提取文件夹X86_64并将其放入ReactAndroid/build/third-party-ndk/jsc/jni/x86_64
    2. 然而,编译将在X86_64上失败并出现错误:lambda capture initializers only available with -std=c++1y or -std=gnu++1y

      1. 通过在-std=c++1y个文件中替换-std=c++11的所有Android.mk来修复该错误。

      2. 现在您可以使用:./gradlew buildReactNdkLib

      3. 开始构建
      4. 您可能需要使用./gradlew cleanReactNdkLib
      5. 清除构建文件夹

        内置reactnativejni - libreactnativejni.so将出现在ReactAndroid/build/react-ndk/all/x86_64

        但遗憾的是libreactnativejni.so无法在Linux上运行,因为它依赖于libandroid.so,而Linux并不存在。