Issue
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:
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?
Solution
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");
Answered By - Alex Cohn
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.