android — вывод ndk-build ‘ошибка при добавлении символов. Файл в неправильном формате

Я хочу использовать библиотеку exiv2, написанную на C ++, в моем проекте Android. Для этого я пытаюсь кросс-компилировать библиотеку с помощью Android NDK.

Для кросс-компиляции я следую представленным ниже шагам:

  1. Добавьте путь ndk в переменную PATH

    $ PATH="/home/patrycja/android-packages/ndk:${PATH}"$ export PATH
    
  2. Установите стандартный набор инструментов для кросс-компиляции C / C ++ для Android.

    ./make-standalone-toolchain.sh --platform=android-21 --install-dir=/tmp/my-android-toolchain --ndk-dir='/home/patrycja/android-packages/ndk/' --toolchain=arm-linux-androideabi-4.9 --system=linux-x86_64
    
    Copying prebuilt binaries...
    Copying sysroot headers and libraries...
    Copying c++ runtime headers and libraries...
    Copying files to: /tmp/my-android-toolchain
    Cleaning up...
    Done.
    
  3. Задайте некоторые переменные среды, чтобы в процессе конфигурации и сборки использовался правильный компилятор.

    $ export PATH=/tmp/my-android-toolchain/bin:$PATH
    $ export CC="arm-linux-androideabi-gcc"$ export CXX="arm-linux-androideabi-g++"$ export CFLAGS='-mthumb -O2'
    $ export CXXFLAGS='-mthumb -O2'
    $ export LDFLAGS='-Wl,--fix-cortex-a8'
    $ export LIBS='-lstdc++ -lsupc++'
    
  4. Bulid статическая библиотека и достаточные заголовки

    ./configure --prefix=$(pwd)/build --host=arm-linux-androideabi --disable-shared --disable-xmp --disable-nls
    

В результате я создал созданные файлы категорий:

    ├── bin
│   └── exiv2
├── include
│   └── exiv2
│       ├── *.hpp
│
├── lib
│   ├── libexiv2.a
│   ├── libexiv2.la
│   └── pkgconfig
│       └── exiv2.pc
└── share
└── man
└── man1
└── exiv2.1

Я скопировал созданную статическую библиотеку libexiv2.a а также include папка для моего проекта Android в appName/src/main/jni/prebuild,

Android.mk похоже:

LOCAL_PATH := $(call my-dir)

#static library info
LOCAL_MODULE := exiv2
LOCAL_SRC_FILES := ../prebuild/libexiv2.a
LOCAL_EXPORT_C_INCLUDES := ../prebuild/include/
LOCAL_EXPORT_LDLIBS := -lz
include $(PREBUILT_STATIC_LIBRARY)#wrapper info
include $(CLEAR_VARS)
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../prebuild/include/
LOCAL_MODULE    := helloJNI
LOCAL_SRC_FILES := helloJNI.cpp
LOCAL_STATIC_LIBRARIES := exiv2
include $(BUILD_SHARED_LIBRARY)

В моей обертке в Android я пытаюсь использовать библиотеку. Это выглядит следующим образом:

#include <string.h>
#include <jni.h>
#include <exiv2/exiv2.hpp>

extern "C" {

JNIEXPORT jstring JNICALL Java_com_example_patrycja_testndi2_MyActivity_helloJNI(JNIEnv *env, jobject thiz)
{
std::ostringstream os;
std::string file("/storage/emmc/DCIM/100MEDIA/IMAG0021.jpg");
Exiv2::Image::AutoPtr image = Exiv2::ImageFactory::open(file);
return env->NewStringUTF("asldjaljd");
}
}

тем не мение ndk-build выводит, что он не может его найти.

[arm64-v8a] Compile++      : helloJNI &lt;= helloJNI.cpp
[arm64-v8a] SharedLibrary  : libhelloJNI.so
jni/../prebuild/libexiv2.a: error adding symbols: File in wrong format
collect2: error: ld returned 1 exit status
make: *** [obj/local/arm64-v8a/libhelloJNI.so] Error 1

Я считаю, что что-то не так с флагами в кросс-компиляции. Я пробовал несколько вариантов, но что-то все еще не так.
Я следовал за этими инструкциями: https://groups.google.com/forum/#!topic/android-ndk/mYh1LzMu_0U

4

Решение

вы скомпилировали exiv2 для ARMv5 + устройства, работающие по крайней мере леденец. Здесь ndk-build терпит неудачу, потому что он пытается связать его с библиотекой arm64-v8a, которую он собирает.

Кросс-компиляцию без использования ndk-build сложно получить прямо на Android, тем более что вы должны поддерживать не только armv5, но и armv7, x86, x86_64, arm64-v8a …

Вы должны сначала установить --platform вариант на тот же уровень, что и ваш минимальный уровень SDK. Затем перестройте свою библиотеку и поместите ее под ../prebuild/armeabi,
Затем выполните кросс-компиляцию вашей библиотеки для архитектуры x86:

./make-standalone-toolchain.sh --platform=android-9 --install-dir=/tmp/my-android-toolchain-x86 --ndk-dir='/home/patrycja/android-packages/ndk/' --arch=x86 --toolchain=x86-4.8 --system=linux-x86_64

$ export PATH=/tmp/my-android-toolchain-x86/bin:$PATH
$ export CC="i686-linux-android-gcc"$ export CXX="i686-linux-android-g++"$ export CFLAGS='-O2 -mtune=atom -mssse3 -mfpmath=sse'
$ export CXXFLAGS='-O2 -mtune=atom -mssse3 -mfpmath=sse'
$ export LDFLAGS=''
$ export LIBS='-lstdc++ -lsupc++'

./configure --prefix=$(pwd)/build-x86 --host=x86 --disable-shared --disable-xmp --disable-nls

и переместить созданный .a в ../prebuild/x86,

В идеале вы должны повторить этот процесс также для armeabi-v7a, mips, mips64, arm64-v8a.

Наконец, вы можете включить право .a внутри вашего Android.mk с использованием TARGET_ARCH_ABI переменная, вот так:

LOCAL_PATH := $(call my-dir)

#static library info
LOCAL_MODULE := exiv2
LOCAL_SRC_FILES := ../prebuild/$(TARGET_ARCH_ABI)/libexiv2.a
LOCAL_EXPORT_C_INCLUDES := ../prebuild/include/
LOCAL_EXPORT_LDLIBS := -lz
include $(PREBUILT_STATIC_LIBRARY)

#wrapper info
include $(CLEAR_VARS)
LOCAL_C_INCLUDES += $(LOCAL_PATH)/../prebuild/include/
LOCAL_MODULE    := helloJNI
LOCAL_SRC_FILES := helloJNI.cpp
LOCAL_STATIC_LIBRARIES := exiv2
include $(BUILD_SHARED_LIBRARY)

и внутри Application.mk (создайте новый файл, если он не существует), укажите архитектуры, которые вы поддерживаете, и минимальную платформу, на которую вы ориентируетесь:

APP_ABI := armeabi x86 # ideally, this should be set to "all"APP_PLATFORM := android-14 # should the same as -platform and your minSdkVersion.
4

Другие решения


По вопросам рекламы [email protected]