libreactnativejni.so построен как elf32-i386 на 64-битном Android ndk (Linux) - PullRequest
0 голосов
/ 24 апреля 2018

РЕДАКТИРОВАТЬ: мне удалось построить x86_64 версию libreactnativejni.so (см. Мой ответ).Однако это не решило мою проблему.

Подводя итог тому, что я узнал здесь:

Вы не можете тестировать компоненты Android, которые используют собственные библиотеки в Linux, потому что "libandroid.so"(ядро android lib), для Linux не существует.

Оригинальный вопрос:

Моя цель - запустить тесты на моем Linux-боксе, используя PowerMockito, похожий на RootViewTest.java .Не уверен, как реал-нативной команде удалось запустить этот тест, но из моего опыта насмешка Arguments.createArray невозможна без загрузки библиотеки jni reactnativejni.Причина в том, что Arguments.createArray() вызывает WritableNativeArray, который в статическом инициализаторе ReactBridge.staticInit () вызывает SoLoader.loadLibrary("reactnativejni").

Так что я подумал, что у меня нет другого выбора, кроме скомпилируйте эту общую библиотеку реагирующая для Linux, используя 64-битную android-ndk-r10e

Мне удалось загрузить эту библиотеку jni и протестировать мой код, используя:

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 голосов
/ 25 апреля 2018

Я собираюсь ответить на свой вопрос (спасибо Алексу за хорошее руководство APP_ABI). Чтобы скомпилировать x86_64 вариант reactnativejni, выполните следующие действия:

  1. Обновить APP_ABI до APP_ABI := armeabi-v7a x86_64 x86 в файле ReactAndroid/src/main/jni/Application.ml

Следующая проблема - это зависимость jsc-android , которая не предназначена для цели X86_64. Существует альтернативный jsc-android-buildscripts , который также построен для X86_64.

  1. Извлеките папку X86_64 прямо из aar и поместите ее в ReactAndroid/build/third-party-ndk/jsc/jni/x86_64

Однако компиляция на 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. При желании вам может потребоваться очистить папку сборки с помощью ./gradlew cleanReactNdkLib

Встроенный reactnativejni - libreactnativejni.so будет присутствовать в ReactAndroid/build/react-ndk/all/x86_64.

Но, к сожалению, libreactnativejni.so не будет работать в Linux, поскольку зависит от libandroid.so, которого нет в Linux.

0 голосов
/ 24 апреля 2018

ReactAndroid явно запрашивает 32-битные цели.Если вы хотите, вы можете заменить эту строку на

APP_ABI := all
...