I want to use the exiv2 library written in C++ in my Android project. To do that, I try to cross-compile the library using the Android NDK.
For cross-compiling, I follow the presented below steps:
Add the NDK path to variable PATH
PATH="/home/patrycja/android-packages/ndk:${PATH}" export PATHInstall the standard toolchain for cross-compiling C/C++ for 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_64Output:
Copying prebuilt binaries... Copying sysroot headers and libraries... Copying c++ runtime headers and libraries... Copying files to: /tmp/my-android-toolchain Cleaning up... Done.Set some environment variables so that the configuration and build process will use the right compiler.
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++'Build the static library and sufficient headers
./configure --prefix=$(pwd)/build --host=arm-linux-androideabi --disable-shared --disable-xmp --disable-nls
As a result, I have created ‘build’ category files:
    ├── bin
    │   └── exiv2
    ├── include
    │   └── exiv2
    │       ├── *.hpp
    │
    ├── lib
    │   ├── libexiv2.a
    │   ├── libexiv2.la
    │   └── pkgconfig
    │       └── exiv2.pc
    └── share
        └── man
            └── man1
                └── exiv2.1
I copied the created static library libexiv2.a and include folder to my Android project in appName/src/main/jni/prebuild.
Android.mk looks like:
LOCAL_PATH := $(call my-dir)
# Static library information
LOCAL_MODULE := exiv2
LOCAL_SRC_FILES := ../prebuild/libexiv2.a
LOCAL_EXPORT_C_INCLUDES := ../prebuild/include/
LOCAL_EXPORT_LDLIBS := -lz
include $(PREBUILT_STATIC_LIBRARY)
# Wrapper information
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)
In my wrapper in Android, I try to use the library. It looks like as follows:
#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");
    }
}
However ndk-build outputs that it can’t find it.
[arm64-v8a] Compile++      : helloJNI <= 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
I believe that there’s something wrong with flags in cross-compiling. I have tried several options, but something is still wrong.
I’ve followed these instructions: How to use an external C++ library from native Android code