How to call JNIHelp.h via NDK? - android-ndk

I am trying to write an JNI file and it includes JNIHelp.h, however I met some error:
jni/JNIMPEG4Writer.cpp:4:21: fatal error: JNIHelp.h: No such file or directory
compilation terminated.
I guess I should add something to the Android.mk file, but I am not sure what should I add. This is my Android.mk file:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := JNIMPEG4Writer
LOCAL_STATIC_LIBRARIES := MPEG4Writer
#LOCAL_LDLIBS := -llog
LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib –llog
LOCAL_SRC_FILES := JNIMPEG4Writer.cpp
include $(BUILD_SHARED_LIBRARY)
Does anyone have any ideas? Thanks!

JNIHelp.h is not part of NDK. You inherited some code from the Android platform. You will find other dependencies on non-public modules, most likely libcutils and libutils.
You have three options: build your code as a module of the platform, rewrite the code to only use public headers and libraries, or download parts of the platform, e.g. https://android.googlesource.com/platform/libnativehelper/, and arrange the include paths accordingly.
To satisfy the linker in the latter scenario, you can use adb pull /system/lib to acquire the versions of libnativehelper.so, libcutils.so, and other referenced non-public libraries. Note that ndk-build will complain about linking against these libraries.

Related

Google Project Tango NDK undefined reference on functions

I am getting a compile error:
undefined reference to 'TangoService_getConfig' (MoreTeapotsNativeActivity.cpp)
ld returned 1 exit status (collect2.exe)
I am working with the tango sdk TangoSDK_Ikariotikos_C.zip in Visual Studio 2015 using VisualGDB. I have also replicated the error in Android Studio so it isn't IDE specific.
I have started with an NDK sample project to test a native activity deploys correctly and reduce complexity whilst troubleshooting. I have used VisualGDB MoreTeaPotsNativeActivity but any will do. The app compiles and runs on our ASUS Zenfone AR. Once I include tango_client_api.h and add the following code, I get the compile error:
TangoCoordinateFramePair* Tango_FramePair;
Tango_FramePair = new TangoCoordinateFramePair();
Tango_FramePair->base = TANGO_COORDINATE_FRAME_START_OF_SERVICE;
Tango_FramePair->target = TANGO_COORDINATE_FRAME_DEVICE;
TangoErrorType retval;
// Connect to tango service.
TangoConfig tango_config;
tango_config = TangoService_getConfig(TANGO_CONFIG_DEFAULT);
The Tango header file has an extern "C" wrapper for the C functions and the .o shows them demangled so I can't see why it is failing.
If I comment out...
//tango_config = TangoService_getConfig(TANGO_CONFIG_DEFAULT);
...it compiles and the enums show as locals in the debug so it seems to be a problem with functions: see image of locals here
I may be missing something glaringly obvious because android is fairly new to me. Perhaps someone can test the tangoSDK library with the same code block and spot the issue. It is frustrating that I cannot even link a library. I may be missing something simple but to me it is not obvious.
Any help will be greatly appreciated.
I contacted Sysprogs Support who gave me a link:
PREBUILT_SHARED_LIBRARY syntax
I hadn't realised the library wasn't being copied even though intellisense was reading the header. I needed to include a reference in the make file (android.mk) to copy the library (I copied Tango include and lib folders to the project jni folder):
include $(CLEAR_VARS)
LOCAL_MODULE := tango_client_api
LOCAL_SRC_FILES := ../jni/lib/$(TARGET_ARCH_ABI)/libtango_client_api.so
include $(PREBUILT_SHARED_LIBRARY)
I did the same with an additional block for the support library:
include $(CLEAR_VARS)
LOCAL_MODULE := tango_support_api
LOCAL_SRC_FILES := ../jni/lib/$(TARGET_ARCH_ABI)/libtango_support_api.so
include $(PREBUILT_SHARED_LIBRARY)
The main module just needs this:
LOCAL_SHARED_LIBRARIES := tango_client_api
The whole file looks like this:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := tango_client_api
LOCAL_SRC_FILES := ../jni/lib/$(TARGET_ARCH_ABI)/libtango_client_api.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := tango_support_api
LOCAL_SRC_FILES := ../jni/lib/$(TARGET_ARCH_ABI)/libtango_support_api.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := MoreTeapotsNativeActivity
#VisualGDBAndroid: AutoUpdateSourcesInNextLine
LOCAL_SRC_FILES := gdbserver_launcher.c MoreTeapotsNativeActivity.cpp MoreTeapotsRenderer.cpp
LOCAL_C_INCLUDES := jni/include
LOCAL_LDLIBS := -llog -landroid -lEGL -lGLESv2
LOCAL_STATIC_LIBRARIES := cpufeatures android_native_app_glue ndk_helper
LOCAL_SHARED_LIBRARIES := tango_client_api
include $(BUILD_SHARED_LIBRARY)
$(call import-module,android/ndk_helper)
$(call import-module,android/native_app_glue)
$(call import-module,android/cpufeatures)
I didn't get this to work straight away when following the NDK examples but Sysprogs gave me feedback on my mistake which I will include.
I tried to include:
LOCAL_MODULE_FILENAME := tango_client_api
I left off the lib and .so as seemed to be convention. The .so was not necessary but taking lib off was changing the file name which caused a link error. That said, that line was unnecessary in the first place to I removed it. Then it removed the error relating to this. I have yet to see if the library works at runtime because I now get this error:
java.lang.UnsatisfiedLinkError: Unable to load native library "/data/app/com.sample.moreteapots-2/lib/arm64/libMoreTeapotsNativeActivity.so": dlopen failed: library "libbinder.so" not found
But this seems to relate to a problem with Android 7.0 platform 24 and higher where
the system prevents apps from dynamically linking against non-NDK libraries
from /Android/android-sdk/docs/about/versions/nougat/android-7.0-changes.html

How to link prebuilt shared/static libraries in ndk build with avoiding the library to get copy in lib/{arch} folder?

I have two native modules to be build as shared library. Both the modules have dependecy on some other common modules.
I am giving the dependecy in Android.mk file using "PREBUILT_SHARED_LIBRARY", but the problem is the libraries specified with "PREBUILT_SHARED_LIBRARY" will get copied to libs/armeabi folder too.. :(
When I include their respective .jars in the main application it throws an eror saying duplicate copy of libraries..
I have to solve this problem by linking the common libraries in ndk build without using "PREBUILT_SHARED_LIBRARY" so that it will not copy the all dependent libraries to libs/areabi.
Can anybody please tell me how can I resolve this problem ? I have googled about this, but everywhere I see the answer use "PREBUILT_SHARED_LIBRARY" to link with already built shared libraries.
Your prebuilt's Android.mk is probably wrong, if you do something like this
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := mygreatlibrary-prebuilt
MY_LIBRARY_NAME := myGreatLibrary
### export include path
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
### path to library
LOCAL_SRC_FILES := libs/$(TARGET_ARCH_ABI)/lib$(MY_LIBRARY_NAME).so
### export dependency on the library
LOCAL_EXPORT_LDLIBS := -L$(LOCAL_PATH)/libs/$(TARGET_ARCH_ABI)/
LOCAL_EXPORT_LDLIBS += -l$(MY_LIBRARY_NAME)
include $(PREBUILT_SHARED_LIBRARY)
Then the correct library will be copied to the correct place

How to build a static library link to a third_part static library using Android ndk

I want to build a static library link to a third_part static library. And then provide the static library which I built to other people to use. But when others use my library, they found an error "undefined reference to 'Func1()'", "Func1()" is a function defined in the third_part static library. Does anyone have an idea how to fix it?
Here's my Android.mk:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := ThirdLib_Rebuild
LOCAL_SRC_FILES := libThird.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := MyLib
LOCAL_STATIC_LIBRARIES := ThirdLib_Rebuild
LOCAL_SRC_FILES := MyLib.c
include $(BUILD_STATIC_LIBRARY)
ndk-build supports transitive dependencies, i.e. if you define a shared library or executable that depends on your MyLib module, then both libMyLib.a and libThird.a will be linked into it (if not, this is a bug, which NDK are you using exactly?).
However, you're not very clear about what you're doing when distributing your libraries to other people. For the record, you need to distribute both libraries to your users, because libMyLib.a does not include the code from libThird.a, the use of LOCAL_STATIC_LIBRARIES in the MyLib module definition only serves to record a dependency between the two libs, unlike what happens when you use it for a shared library or executable.

Android NDK build error . do not found libcutils.so

i want to build the expolid code ( https://github.com/revolutionary/zergRush/blob/master/zergRush.c)
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := zergRush
LOCAL_SRC_FILES := zergRush.c
base :=E:\0.Android\system\core
#//base path include the android source code. but i forget the version .maybe 4.0.1
LOCAL_C_INCLUDES :=$(base)/include/
LOCAL_LDLIBS := -llog -lcutils
LOCAL_STATIC_LIBRARIES := libcutils libc
LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
LOCAL_MODULE_TAGS := eng debug
LOCAL_FORCE_STATIC_EXECUTABLE := true
include $(BUILD_EXECUTABLE)
this computer has installed ndk-r9b.
libcutils.so : D:\android-ndk-r9b\platforms\android-19\arch-arm\usr\lib\rs
so i copy it to D:\android-ndk-r9b\platforms\android-19\arch-arm\usr\lib.
default.properties project.properties set target=19
but ndk-build failed .
D:\test\roottest\jni>ndk-build
[armeabi] Compile thumb : zergRush <= zergRush.c
[armeabi] Executable : zergRush
D:/android-ndk-r9b/toolchains/arm-linux-androideabi-4.6/prebuilt/windows-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6
/../../../../arm-linux-androideabi/bin/ld.exe: error: cannot find -lcutils
D:/android-ndk-r9b/toolchains/arm-linux-androideabi-4.6/prebuilt/windows-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6
/../../../../arm-linux-androideabi/bin/ld.exe: D:/test/roottest//obj/local/armeabi/objs/zergRush/zergRush.o: in function
do_fault:D:/test/roottest//jni/zergRush.c:226: error: undefined reference to 'socket_local_client'
D:/android-ndk-r9b/toolchains/arm-linux-androideabi-4.6/prebuilt/windows-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6
/../../../../arm-linux-androideabi/bin/ld.exe: D:/test/roottest//obj/local/armeabi/objs/zergRush/zergRush.o: in function
main:D:/test/roottest//jni/zergRush.c:488: error: undefined reference to 'property_set'
D:/android-ndk-r9b/toolchains/arm-linux-androideabi-4.6/prebuilt/windows-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6
/../../../../arm-linux-androideabi/bin/ld.exe: D:/test/roottest//obj/local/armeabi/objs/zergRush/zergRush.o: in function
main:D:/test/roottest//jni/zergRush.c:619: error: undefined reference to 'property_get'
collect2: ld returned 1 exit status
make.exe: *** [D:/test/roottest//obj/local/armeabi/zergRush] Error 1
i want to know how to include the use-defined libraray path or include libcutils.so and i can make the program . thanks.
The correct syntax in project.properties file is target=android-19. Make sure that you have it that way. If you want to make sure it works, open up your project in Eclipse, right-click on it and select to open its Properties.
Also, you've listed libcutils as both a shared library and a static library in your makefile. libc is also a shared library in Android system, so I'm pretty sure that you ought to do without the entire LOCAL_STATIC_LIBRARIES line.
If fixing the target still does not work, my advice would be to add libcutils.so as a "prebuilt" library (check your <ndk>/docs/PREBUILTS.html file to see how to do that).
Good luck!

Trouble w/ std::string when building C++ code in ndk environment

I'm working on some code cuz I was asked to devlep c++ code about core part of a program.
But, it's my first time to use ndk so, I had some troubles and resolved that.
However, too difficult problem is coming to me. I had building my c++ code w/ ndk but,
it said,
.h:3:20: error: string: No such file or directory
.h:5: error: 'std::string' has not been declared
and any other errors about that.
Below is my 'Android.mk' file I wrote:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := clibs
LOCAL_SRC_FILES := sqlite3.c
LOCAL_LDLIBS := -llog
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_DEFAULT_CPP_EXTENSION := cpp
LOCAL_MODULE := mytweetlib
LOCAL_STATIC_LIBRARIES := clibs
LOCAL_SRC_FILES := Friend.cpp SQLiteDB.cpp Cursor.cpp DB4Friends.cpp ResultParser.cpp MyTweet.cpp Stub.cpp
include $(BUILD_SHARED_LIBRARY)
I tried to link the .c file(sqlite3.c) Making static library file w/ the other file(to be built to shared library).
Is there anyone knows about this? Even if it's just very little clue, plz give me that.
(I haven't been resolving this problem)
It looks like the NDK isn't being told to use stl port.
Try adding an Application.mk file containing APP_STL. This adds the stlport headers to the include path, and links against the libraries.
APP_STL := stlport_static
I would like to add further to Piklor answer.
Do not confuse with "Android.mk" file with "Application.mk" , in your jni folder.
Also your include should include string not string.h

Resources