AndroidNDKからlibxmlのライブラリを使用する

2016年9月22日

以前ビルドした ndk-build 版 libxml ですが、ndk-build するプロジェクト内で読み込む場合の Android.mk の書き方について、まとめておきます。
以降、libxml を静的ライブラリとしてビルドした前提で話をしていますが、共有ライブラリとしてビルドした場合でも同じように読み込めると思います。

作成したライブラリをロードする際に「dlopen」でエラーが出る方は、最後の余談のところが参考になるかもしれません。

今回は、jni フォルダ直下にライブラリやヘッダファイル用のディレクトリをそれぞれ作成して利用することにします。

  1. libxml のヘッダファイル群の設定

libxml を使用するプロジェクトのフォルダ(以下、SampleLibrary とします)直下に “headers” フォルダを追加します。
作成した “headers” フォルダ内に、libxml2-2.9.1/include/ にある “libxml” フォルダをフォルダごとコピーします。
フォルダ階層は、jni/headers/libxml/ となります。

  1. libxml のプラグイン群の設定

ビルドした .a ファイル群をコピーしてきます。
今回は、jni 以下に “lib” フォルダを追加して、ここにプラグインを置くことにします。
libxml2-2.9.1/obj/local/ 以下にあるフォルダをすべてコピーして、jni/lib/ 以下にペーストします。

  1. Android.mk の設定
    今回は jni フォルダ直下の Android.mk から libxml を読み込みます。
    Android.mk での設定は、以下のようになります。
include $(CLEAR_VARS)
LOCAL_MODULE := SampleLibrary
LOCAL_SRC_FILES := SampleLibrary.cpp
LOCAL_C_INCLUDES := $(LOCAL_PATH)/headers/
LOCAL_LDLIBS := -llog -L$(LOCAL_PATH)/lib/$(TARGET_ARCH_ABI)/
LOCAL_ALLOW_UNDEFINED_SYMBOLS := true
include $(BUILD_SHARED_LIBRARY)

要点は以下の項目です。
・LOCAL_C_INCLUDE に、ヘッダファイル群へのパスを追加
・LOCAL_LDLIBS に、プラグインへのパスを追加
・LOCAL_ALLOW_UNDEFINED_SYMBOLS := true を追加

最後の LOCAL_ALLOW_UNDEFINED_SYMBOLS は、原因のわからないリンクエラーになったのでしばらく悩みました。
これを宣言しないと、xmlstring.h や xpath.h などの API が参照できないようです。

最終的には、stackoverlow に助けてもらいました。
ndk-build: undefined reference to .. errors when statically linking to libxml.a
(http://stackoverflow.com/questions/7209971/ndk-build-undefined-reference-to-errors-when-statically-linking-to-libxml-a)

  1. 実装
    これで、SampleLibrary 内で libxml の API を呼び出せるようになります。

余談:
Android.mk の LOCAL_SRC_FILES に buf.c を書き忘れたせいで、ライブラリのロード時にクラッシュするというめんどくさい問題が発生しました。dlopen のエラーが出たので、同じような現象が発生した人は、Android.mk を確認すると幸せになれるかもしれません。

おしまい。

スポンサーリンク