Android プロジェクトで C++ で記述された exiv2 ライブラリを使用したいと考えています。そのために、Android NDK を使用してライブラリをクロスコンパイルしてみます。
クロスコンパイルについては、以下の手順に従います。
ndk パスを変数 PATH に追加します
$ PATH="/home/patrycja/android-packages/ndk:${PATH}" $ export PATH
Android 用の C/C++ をクロスコンパイルするための標準ツールチェーンをインストールします。
./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.
構成とビルド プロセスで適切なコンパイラが使用されるように、いくつかの環境変数を設定します。
$ 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++'
静的ライブラリと十分なヘッダーを構築する
./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 <= 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