سؤال

I am trying to import the TagLib C++ library (http://taglib.github.io/) to Android using the NDK.

I was able to successfully compile the library by putting all the source code under /jni/taglibroot/ as per picture bellow:

enter image description here

and running ndk-build on the /jni folder.

However, I have also created the tag_lib_personal.cpp file bellow (to use the TagLib API):

#include <jni.h>
/*#include <iostream>
#include <iomanip>*/
#include <stdio.h>

#include <taglibroot/taglib/fileref.h>
#include <taglibroot/taglib/tag.h>
#include <taglibroot/taglib/tpropertymap.h>


#ifdef __cplusplus
extern "C"
{
#endif

    jstring Java_com_mindtherobot_samples_ndkfoo_NdkFooActivity_invokeNativeFunction(JNIEnv* env, jobject javaThis) {

      TagLib::FileRef f(argv[i]);

      if(!f.isNull() && f.audioProperties()) {

        TagLib::AudioProperties *properties = f.audioProperties();

        int seconds = properties->length() % 60;
        int minutes = (properties->length() - seconds) / 60;

        /*cout << "-- AUDIO --" << endl;
        cout << "bitrate     - " << properties->bitrate() << endl;
        cout << "sample rate - " << properties->sampleRate() << endl;
        cout << "channels    - " << properties->channels() << endl;
        cout << "length      - " << minutes << ":" << formatSeconds(seconds) << endl;*/
      }

      return "hello world!";

      //return (*env)->NewStringUTF(env, "Hello from native code!");
}

#ifdef __cplusplus
}
#endif

But I cannot get it to compile. When I try to run ndk-build again I get the following error:

[armeabi] Compile++ arm  : my_own_source_files <= tag_lib_personal.cpp
In file included from D:/blabla/eclipse-jee-indigo-SR2-win32-x86_64/workspace/Project//jni/tag_lib_personal.cpp:7:0:
D:/blabla/eclipse-jee-indigo-SR2-win32-x86_64/workspace/Project//jni/taglibroot/taglib/fileref.h:29:19: fatal error: tfile.h: No such file or directory
compilation terminated.
make.exe: *** [D:/blabla/eclipse-jee-indigo-SR2-win32-x86_64/workspace/Project//obj/local/armeabi/objs/my_own_source_files/tag_lib_personal.o] Error 1

The error shows it cannot find some .h files from the TagLib library. Here is my Android.mk file though:

LOCAL_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := taglib_module
FILE_LIST := $(wildcard $(LOCAL_PATH)/taglibroot/*.cpp) #Based on: http://stackoverflow.com/a/8980441
LOCAL_SRC_FILES := $(FILE_LIST:$(LOCAL_PATH)/%=%)


LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/foo
LOCAL_EXPORT_CFLAGS := -DFOO=1
LOCAL_EXPORT_LDLIBS := -llog

LOCAL_ARM_MODE := arm

include $(BUILD_SHARED_LIBRARY)
# If I run ndk-build only on the above code, it compiles the TagLib library successfully and generates the .so files as expected


include $(CLEAR_VARS)
LOCAL_MODULE := my_own_source_files
LOCAL_SHARED_LIBRARIES := taglib_module
LOCAL_SRC_FILES := tag_lib_personal.cpp
LOCAL_C_INCLUDES := $(LOCAL_PATH)/taglibroot/taglib,\
                    $(LOCAL_PATH)/taglibroot/taglib/ape,\
                    $(LOCAL_PATH)/taglibroot/taglib/asf,\
                    $(LOCAL_PATH)/taglibroot/taglib/flac,\
                    $(LOCAL_PATH)/taglibroot/taglib/it,\
                    $(LOCAL_PATH)/taglibroot/taglib/mod,\
                    $(LOCAL_PATH)/taglibroot/taglib/mp4,\
                    $(LOCAL_PATH)/taglibroot/taglib/mpc,\
                    $(LOCAL_PATH)/taglibroot/taglib/mpeg,\
                    $(LOCAL_PATH)/taglibroot/taglib/mpeg/id3v1,\
                    $(LOCAL_PATH)/taglibroot/taglib/mpeg/id3v2,\
                    $(LOCAL_PATH)/taglibroot/taglib/mpeg/id3v2/frames,\
                    $(LOCAL_PATH)/taglibroot/taglib/ogg,\
                    $(LOCAL_PATH)/taglibroot/taglib/ogg/flac,\
                    $(LOCAL_PATH)/taglibroot/taglib/ogg/opus,\
                    $(LOCAL_PATH)/taglibroot/taglib/ogg/speex,\
                    $(LOCAL_PATH)/taglibroot/taglib/ogg/vorbis,\
                    $(LOCAL_PATH)/taglibroot/taglib/riff,\
                    $(LOCAL_PATH)/taglibroot/taglib/riff/aiff,\
                    $(LOCAL_PATH)/taglibroot/taglib/riff/wav,\
                    $(LOCAL_PATH)/taglibroot/taglib/s3m,\
                    $(LOCAL_PATH)/taglibroot/taglib/toolkit,\
                    $(LOCAL_PATH)/taglibroot/taglib/trueaudio,\
                    $(LOCAL_PATH)/taglibroot/taglib/wavpack,\
                    $(LOCAL_PATH)/taglibroot/taglib/xm

LOCAL_ARM_MODE := arm

include $(BUILD_SHARED_LIBRARY)

As you can see I put every single directory of the TagLib library that has at least one .h file in the LOCAL_EXPORT_C_INCLUDES directive but it for some reason still cannot find tfile.h (which is inside $(LOCAL_PATH)/taglibroot/taglib/toolkit). What am I missing?

هل كانت مفيدة؟

المحلول

You are not missing, you have an extra ;-)

Syntax for LOCAL_C_INCLUDES does not expect these commas. You simply list all directories. Actually, you can use LOCAL_EXPORT_C_INCLUDES instead (your post hints that you probably tried):

LOCAL_C_INCLUDES := $(LOCAL_PATH)/taglibroot/taglib\
                $(LOCAL_PATH)/taglibroot/taglib/ape\
                $(LOCAL_PATH)/taglibroot/taglib/asf\
                $(LOCAL_PATH)/taglibroot/taglib/flac\
                $(LOCAL_PATH)/taglibroot/taglib/it\
                $(LOCAL_PATH)/taglibroot/taglib/mod\
                $(LOCAL_PATH)/taglibroot/taglib/mp4\
                $(LOCAL_PATH)/taglibroot/taglib/mpc\
                $(LOCAL_PATH)/taglibroot/taglib/mpeg\
                $(LOCAL_PATH)/taglibroot/taglib/mpeg/id3v1\
                $(LOCAL_PATH)/taglibroot/taglib/mpeg/id3v2\
                $(LOCAL_PATH)/taglibroot/taglib/mpeg/id3v2/frames\
                $(LOCAL_PATH)/taglibroot/taglib/ogg\
                $(LOCAL_PATH)/taglibroot/taglib/ogg/flac\
                $(LOCAL_PATH)/taglibroot/taglib/ogg/opus\
                $(LOCAL_PATH)/taglibroot/taglib/ogg/speex\
                $(LOCAL_PATH)/taglibroot/taglib/ogg/vorbis\
                $(LOCAL_PATH)/taglibroot/taglib/riff\
                $(LOCAL_PATH)/taglibroot/taglib/riff/aiff\
                $(LOCAL_PATH)/taglibroot/taglib/riff/wav\
                $(LOCAL_PATH)/taglibroot/taglib/s3m\
                $(LOCAL_PATH)/taglibroot/taglib/toolkit\
                $(LOCAL_PATH)/taglibroot/taglib/trueaudio\
                $(LOCAL_PATH)/taglibroot/taglib/wavpack\
                $(LOCAL_PATH)/taglibroot/taglib/xm

Note If you encounter strange issues with ndk-build in the future, first advice is to run ndk-build V=1: it will log all actual compilation commands used by ndk-build, which may often expose the errors or typos in various Android.mk files.

PS Your build will finally fail. When you build taglib, you need also to compile all .cpp files in taglibroot subdirectories! I suggest that you try to build the library the way it was designed to be built, with CMake. The Android patches can be found here: https://code.google.com/p/android-cmake.

You can also try a straightforward approach, but I am not sure it will work:

MY_PATH := $(call my-dir)

include $(CLEAR_VARS)
LOCAL_MODULE := taglib_module
LOCAL_PATH := $(MY_PATH)/taglibroot/taglib
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)\
        $(LOCAL_PATH)/ape\
        $(LOCAL_PATH)/asf\
        $(LOCAL_PATH)/flac\
        $(LOCAL_PATH)/it\
        $(LOCAL_PATH)/mod\
        $(LOCAL_PATH)/mp4\
        $(LOCAL_PATH)/mpc\
        $(LOCAL_PATH)/mpeg\
        $(LOCAL_PATH)/mpeg/id3v1\
        $(LOCAL_PATH)/mpeg/id3v2\
        $(LOCAL_PATH)/mpeg/id3v2/frames\
        $(LOCAL_PATH)/ogg\
        $(LOCAL_PATH)/ogg/flac\
        $(LOCAL_PATH)/ogg/opus\
        $(LOCAL_PATH)/ogg/speex\
        $(LOCAL_PATH)/ogg/vorbis\
        $(LOCAL_PATH)/riff\
        $(LOCAL_PATH)/riff/aiff\
        $(LOCAL_PATH)/riff/wav\
        $(LOCAL_PATH)/s3m\
        $(LOCAL_PATH)/toolkit\
        $(LOCAL_PATH)/trueaudio\
        $(LOCAL_PATH)/wavpack\
        $(LOCAL_PATH)/xm

FILE_LIST := $(foreach dir, $(LOCAL_EXPORT_C_INCLUDES), $(wildcard $(dir)/*.cpp))
LOCAL_SRC_FILES := $(FILE_LIST:$(LOCAL_PATH)/%=%)

LOCAL_EXPORT_CFLAGS := -DFOO=1
LOCAL_EXPORT_LDLIBS := -llog

LOCAL_ARM_MODE := arm

include $(BUILD_SHARED_LIBRARY)

include $(CLEAR_VARS)
LOCAL_PATH := $(MY_PATH)
LOCAL_MODULE := my_own_shared_lib
LOCAL_SHARED_LIBRARIES := taglib_module
LOCAL_SRC_FILES := tag_lib_personal.cpp

LOCAL_ARM_MODE := arm

include $(BUILD_SHARED_LIBRARY)

Please note that in your Java, you will load the two libraries, and order is important:

Runtime.loadLibrary("taglib_module");
Runtime.loadLibrary("my_own_shared_lib");
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top