I use PTAM code taken from here. I try to make an android application with this code.
The PTAM code uses libcvd, TooN, gvars3 library. I generate a .so file from my c++ test file using ndk-build.
Firstly, I try to run below code on android phone :
#include <string.h>
#include <jni.h>
extern "C" {
int returnInt()
{
int returnVal = 4;
return returnVal;
}
}
It can generate .so file without any errors. If I add #include < TooN/TooN.h > , `ndk-build says that
fatal error: TooN/TooN.h: No such file or directory
#include <TooN/TooN.h>
^
compilation terminated.
Android.mk is :
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := test-jni
LOCAL_SRC_FILES := test-jni.cpp
include $(BUILD_SHARED_LIBRARY)
How can I solve this error message?
fatal error: TooN/TooN.h: No such file or directory
#include <TooN/TooN.h>
When you use <> with #include, the compiler will search for the file in your include path (and possibly other predefined directories).
To add a directory to your include path when building a module in Android.mk you would add it to LOCAL__INCLUDES. For example, if the full path to TooN.h is /home/foobar/TooN/TooN.h you should do this:
LOCAL_C_INCLUDES += /home/foobar
I get fatal error: iostream: No such file or directory.There is no folder named iostream under usr/include or usr/local/include.
The iostream class is part of the STL, so you need to specify an STL implementation to build against. This can be done using the APP_STL variable in Application.mk. For example:
APP_STL := gnustl_shared
See this page for a list of STL implementations available with the NDK.
Related
I'm trying to modify this tutorial to include a prebuilt C library in my Android Studio project (ie. not using the experimental Gradle plugin) http://kvurd.com/blog/compiling-a-cpp-library-for-android-with-android-studio/
The library itself is coming from a client who won't reveal the source code, therefore I have no control over that part of the build process, however they are already following the same tutorial.
The project builds, load-library works and the NDK link (/jni/my-wrapper.c) works fine, until I try to call the actual library function defined in my prebuild header. The error I'm receiving is:
$ ndk-build
[arm64-v8a] Compile : my-wrapper <= my-wrapper.c
[arm64-v8a] SharedLibrary : libmy-wrapper.so
/Users/me/AndroidStudioProjects/MyProject/app/obj/local/arm64-v8a/objs/my-wrapper/my-wrapper.o: In function `Java_com_my_project_SignInActivity_CallFunction':
/Users/me/AndroidStudioProjects/MyProject/app/jni/my-wrapper.c:44: undefined reference to `MyFunction'
collect2: error: ld returned 1 exit status
make: *** [/Users/me/AndroidStudioProjects/MyProject/app/obj/local/arm64-v8a/libmy-wrapper.so] Error 1
Here's my Android.mk:
LOCAL_PATH := $(call my-dir)
# static library info
include $(CLEAR_VARS)
LOCAL_MODULE := libMyLib
LOCAL_MODULE_FILENAME := libMyLib
LOCAL_SRC_FILES := ../prebuild/libMyLib.a
LOCAL_EXPORT_C_INCLUDES := ../prebuild/include
include $(PREBUILT_STATIC_LIBRARY)
# wrapper info
include $(CLEAR_VARS)
LOCAL_C_INCLUDES += ../prebuild/include
LOCAL_MODULE := my-wrapper
LOCAL_SRC_FILES := my-wrapper.c
LOCAL_STATIC_LIBRARIES := libMyLib
include $(BUILD_SHARED_LIBRARY)
And MyLib.h (note that foobar() works fine as it's in the header but as long as I'm calling MyFunction from within my-wrapper.c the ndk-build fails):
#include <math.h>
#include <setjmp.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int MyFunction(some stuff);
int foobar(){return 1;};
Finally, my-wrapper.c:
#include <MyLib.h>
jbyte Java_com_my_project_SignInActivity_MyFunction(JNIEnv *env, jobject thiz, some other stuff){
// return MyFunction(some other stuff which I cast to C types); //linker fails if uncommented
return foobar(); //works fine
}
That's a C++ mangled name. You can only use it from C++, not from C.
If you really need to call it from C, you might be able to do it like so:
extern int _Z12MyFunctionP9my_structPhS1_S1_(/* whatever the function args are */);
jbyte Java_com_my_project_SignInActivity_MyFunction(
JNIEnv *env, jobject thiz, some other stuff) {
return _Z12MyFunctionP9my_structPhS1_S1_(args);
}
That depends on the code you're calling being compatible as such (if that's the case, you should ask the client to build their APIs as extern "C").
I'd really recommend just moving your code to C++ though.
i wrote a simple C++ Programm using NDK, and it works fine.
Now I want to add the following header file for using logging functions:
android\log.h
My Android.mk look like this:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_LDLIBS:= -llog
LOCAL_MODULE := ndkmodulea
LOCAL_SRC_FILES := ndkmodulea.cpp
include $(BUILD_SHARED_LIBRARY)
My .cpp file starts like this:
#include <jni.h>
#include <string.h>
#include <android\log.h>
if i try to run ndk-build (via terminal) inside the android project folder,
I'll get following error message:
Compile++ thumb : ndkmodulea <= ndkmodulea.cpp
jni/ndkmodulea.cpp:4:25: fatal error: android\log.h: No such file or directory
compilation terminated.
make: *** [obj/local/armeabi/objs/ndkmodulea/ndkmodulea.o] Error 1
Can somebody help or teach me how to correctly include such header files?
Many thanks in advance!
Use forward slashes in #include paths:
#include <android/log.h>
I'm trying to build a wraper using some old C++ code in Android.
When compiling the errors bellow are shown:
In file included from /usr/local/android/android-ndk-r8b/sources/cxx-stl/gnu-libstdc++/4.6/include/bits/stl_algobase.h:61:0,
from /usr/local/android/android-ndk-r8b/sources/cxx-stl/gnu-libstdc++/4.6/include/bits/stl_tree.h:63,
from /usr/local/android/android-ndk-r8b/sources/cxx-stl/gnu-libstdc++/4.6/include/map:60,
from /home/vocalize/source/xxxxxxxxxxxxxxxxxxxxx/Lxxxxxxx.h:9,
from /home/vocalize/source/xxxxxxxxxxxxxxxxx/jni/cxxx_wrap.c:3:
/usr/local/android/android-ndk-r8b/sources/cxx-stl/gnu-libstdc++/4.6/include/bits/functexcept.h:43:1: error: unknown type name 'namespace'
/usr/local/android/android-ndk-r8b/sources/cxx-stl/gnu-libstdc++/4.6/include/bits/functexcept.h:44:1: error: expected ',' or ';' before '{' token
I'm using the following Makefile.mk
include $(CLEAR_VARS)
LOCAL_C_INCLUDES := $(MY_LIB_DIR)include
LOCAL_CFLAGS += -DHAVE_CONFIG_H
LOCAL_CFLAGS += -DANDROID_NDK
LOCAL_PATH := $(BASE_PATH)
LOCAL_MODULE := cxxxx_lib
LOCAL_SRC_FILES := cxxxx_wrap.c
LOCAL_STATIC_LIBRARIES := my_lib
LOCAL_LDLIBS := -llog
include $(BUILD_SHARED_LIBRARY)
What I can do to fix these errors?
A C++ .h file is being included from cxxx_wrap.c, which is a .c file. The compiler uses the extension of the source file to detect the language. So it's assuming C, and choking on the C++-specific syntax.
Rename cxxx_wrap.c to .cpp or .cxx. Or surround the #include "Lxxxxxxx.h" line with #ifdef __cplusplus/#endif. Or force C++ compilation by specifying -x c++ compiler option.
Once you do, make sure all JNI methods in cxxx_wrap are declared with JNIEXPORT or surrounded with extern "C" {}. Otherwise, the Java run-time won't find them.
For the record: renaming the .h file to .hpp won't help.
I've seen questions similar to this one, but the scenarios are not exactly the same, nor can I get an answer that works on my problem.
I have the source code for a C++ library. We need to use this library as part of an android application but it also needs to be available for third party to use as a C++ library.
I have a makefile that generates the .a file out of the library's source code, using ndk's compiler. That's the pure C++ part.
On the Java part, I have a simple demo project with a simple activity containing a button. When the button is pressed a call to native code is made.
Everything works fine as long as I don't try to call a function from the library from the JNI function.
Here are the sources for the library:
SimpleMath.h
int Add(int aNumber1, int aNumberB);
SimpleMath.cpp
#include "SimpleMath.h"
int Add(int aNumberA, int aNumberB)
{
return aNumberA + aNumberB;
}
The makefile
APP = simple_app
LIBRARY = simple_library.a
OBJECTS = SimpleMath.o
CFLAGS = -Wall -pedantic
NDK_PATH = /home/jug/perforce/jug_navui_personal_main/Env/Linux/Android/ndk/r7c
CXX = $(NDK_PATH)/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-g++
AR = $(NDK_PATH)/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/arm-linux-androideabi-ar
SYSTEM_LIBS = -lstdc++ -lm
INCLUDE_PATH += ${NDK_PATH}/platforms/android-9/arch-arm/usr/include
all: $(LIBRARY)
$(LIBRARY):
$(CXX) -c SimpleMath.c
$(AR) rcs simple_library.a SimpleMath.o
clean:
rm *.o *.a
On the java side, these are the files:
hello-jni.c
#include <string.h>
#include <jni.h>
#include "../../../native/simple_library/SimpleMath.h"
jstring Java_com_amstapps_samples_draft08jni_MainActivity_helloJni(JNIEnv* env, jobject obj)
{
// Uncommenting the line below results in undefined-symbol compile error
//int d = Add(1, 2);
return (*env)->NewStringUTF(env, "Hello from JNI!");
}
Android.mk
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := my_simple_library
LOCAL_ARM_MODE := arm
LOCAL_SRC_FILES := ../../../native/simple_library/simple_library.a
include $(PREBUILT_STATIC_LIBRARY)
#include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := eng
LOCAL_ARM_MODE := arm
#LOCAL_PRELINK_MODULE := false
LOCAL_MODULE := hello-jni
LOCAL_SRC_FILES := hello-jni.c
LOCAL_C_INCLUDES := ../../../android/native/simple_library
LOCAL_STATIC_LIBRARIES := my_simple_library
#LOCAL_WHOLE_STATIC_LIBRARIES := my_simple_library
include $(BUILD_SHARED_LIBRARY)
Application.mk
APP_MODULES := my_simple_library hello-jni
As I said, the problem comes when I to actually make use of the functionality in the library from the jni native code in java application.
Now, I'm not longer sure whether my problem is in the static-library's makefile or on the Android.mk. I first thought it must have to do with the generation of the library itself, but at this point, after seeing there are so many options I didn't know about in Android.mk, I have to admit I have no clue.
What else..?
Oh, yes, I also noticed my pure C++ library is using cpp extension whereas the jni code in java project is using c extension. I tried to have the latter using cpp as well, but compiler complains. Could this be part of the problem?
The error code that I get when trying to compile the Android.mk file is "undefined symbol", so, is the list of functions in simple_library.a (there's actually 1 function) not visible to hello-jni.c because of it being C++ and not plain C?
Another thing you might notice is I'm trying to build the static library on its own makefile as opposed to generating it with Android.mk; there's a reason for that, but at this point I would also be happy if I had to have it in generated by Android.mk if that's what it takes.
I don't see any way to add an attachment in here so that to share a zip with the project.
Let me know if there's something I'm missing.. Otherwise the code is in a depot in bitbucket, so I can easily share it with anyone having an account there too.
Thanks for you answers.
You write a lot of correct things, but you're missing just one.
The function's name gets mangled in C++. And in the .so file you do not get "Add" symbol, but something like "Add#8i". To avoid mangling just use the
extern "C" int Add(int x, int y)
declaration in the .cpp file and in the .h.
Usually one also adds the
/// Some .h file
#ifdef __cplusplus
extern "C" {
#endif
/// Your usual C-like declarations go here
#ifdef __cplusplus
} // extern "C"
#endif
And the
extern "C"
for each of the exported functions in the .cpp file.
I m trying to build an app with android-froyo source in which I am using skia and stl templates,
I have included
MY_INCLUDES=external/zlib external/jpeg external/freetype/include \
frameworks/base/core/jni/android/graphics external/skia/include/core \
external/libpng external/expat/lib <b>external/stlport/stlport</b>
libstlport_cflags := -D_GNU_SOURCE
libstlport_cppflags := -fuse-cxa-atexit
LOCAL_CPPFLAGS := $(libstlport_cppflags)
include $(BUILD_STATIC_LIBRARY)
I get the following error when i try to build the android source with this app, which i kept at packages/apps:
external/stlport/stlport/stl/_new.h:47:50: error: libstdc++/include/new: No such file or directory
Please guide me to rectify this issue.
Thanks
Mohit
As I understand the file which cannot be found by preprocessor is located in bionic folder.
I had the same issue and I solved it by adding the following line:
LOCAL_C_INCLUDES += bionic
I haven't tried this with Android 2.2 but I'm using Android Kitkat (4.4).
To get the stlport library working with our project we included it in our project's Android.mk as so:
include external/stlport/libstlport.mk
This is assuming that on Froyo, there is a libstlport.mk file to include in your build process. In 4.4, there is also a Android.mk file but that builds other code as well and builds stlport as a static library (which is not what we wanted).
You may need to also add the include directory as well, something like: external/stlport/stlport.
cpp
#include <stdio.h>
// The code
// The set of definitions and includes for STLPort
// They used defined() instead of #ifdef.
#define _STLP_HAS_INCLUDE_NEXT 1
#define _STLP_USE_MALLOC 1
#define _STLP_USE_NO_IOSTREAMS 1
#include <stl/config/_android.h>
#include <map>
#include <string>
int main(void)
{
std::string a = "abc";
printf("%s",a.c_str());
return 0;
}
Android.mk
# A simple test for the minimal standard C++ library
#
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := test-libstl.cpp
LOCAL_C_INCLUDES += sources/cxx-stl/stlport/stlport
LOCAL_SHARED_LIBRARIES += libstlport
LOCAL_MODULE := test-libstl
include $(BUILD_EXECUTABLE)