I added some new functionality in C and when I try to build it, it gives me the following error:
libnativehelper/include/nativehelper/JNIHelp.h:116: error: undefined reference to 'jniRegisterNativeMethods' error.
I have included jnihelp.h in my C files.
Is this a makefile related issue or am I missing something?
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE_TAGS := optional
LOCAL_MODULE := newfile
LOCAL_SRC_FILES := newfile.cpp
include $(BUILD_SHARED_LIBRARY)
EDIT 6/5/14: I finally fixed it. Just thought I'd put all the info here in case someone else needs it.
The manifest had to be modified to load certain libraries as mentioned in my comment below.This was to fix the undefined reference to 'jniRegisterNativeMethods' error
The cpp file that had the native implementation had to be inside an extern "C" block. This was causing the UnsatisfiedLinkError.
You need to go to parent folder where you have your build and dalvik binaries. Then from there you need to type:
build yourproj
(replace yourproj with folder you have your codes in it)
I found the issue was indeed in the makefile
I looked around for other JNI implementations and added this to the makefile
LOCAL_SHARED_LIBRARIES := \
libandroid_runtime \
libandroidfw \
libnativehelper \
libRS \
libcutils \
libskia \
libutils
I have no idea what a few of the libraries in there are for, but I left them there and it compiled.
Now I have a different issue. I get the 'Unsatified Link error' when I load the compiled library. Does anyone have an idea on this?
Edit: My compiled libraries are being transferred to the phone. I manually pushed them onto the /system/lib directory on the phone but I still get the 'UnsatisfiedLinkError'.
Related
Many related questions have been asked regarding NDK linker errors, but I couldnt clearly found a solution to my situation.
I am trying to extend a sample NDK applicaiton, by adding 4 more local files of my own.
I am including them in the Android.mk file, and including the .h files appropriately.
Here is my Android.mk file.
include $(BUILD_SHARED_LIBRARY)
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libgl2jni
LOCAL_CFLAGS := -Werror
LOCAL_SRC_FILES := gl_code.cpp \
sglBandwidthBench.c \
sglBandwidth.c \
common.c \
timer.c
LOCAL_LDLIBS := -llog -lGLESv3 -lEGL
include $(BUILD_SHARED_LIBRARY)
and the .h files inclusion has been proper. but the compilation gives me undefined reference to function x.
I added the files sglBandwidthBench.c sglBandwidth.c common.c timer.c, none of them contain a main function, and the only link is through referecing one of those functions in gl_code.cpp.
how can I link these files together successfully? I couldnt think of any way of specifying it. Any help would be much appreciated.
As you may know, link errors on undefined references are due to one or more method's implemetation not being found by the build system inside the prebuit libraries you provided. So, bottom line, you are probably missing the shared library which contains the implementation for function x.
My advice would be to double-check if you actually have libGLESv3.so under any of your <ndk>\platforms\<android-api-level>\arch-arm\usr\lib directory. Alternatively, check <ndk>\docs\STABLE-APIS.html to see if all the libraries you're using are listed there. If one of them is not, you will either need to upgrade your NDK version or to manually add the missing library to your source code (for that, read section PREBUILT_SHARED_LIBRARY from <ndk>\docs\ANDROID-MK.html).
Hope that this helps!
EDIT: Hi Sai, from what I just learned from your comments, you are trying to call a method implemented in a .c file from inside a .cpp one. So you need to enclose the contents of your gl_code.cpp with the following piece of code:
#ifdef __cplusplus
extern "C" {
#endif
#ifdef __cplusplus
}
#endif
Following is my MAKE file for the source that i'm compiling with the build AOSP
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES:= abc.c
LOCAL_MODULE:= abc
LOCAL_FORCE_STATIC_EXECUTABLE := true
LOCAL_STATIC_LIBRARIES := libc
LOCAL_MODULE_PATH := $(TARGET_OUT_OPTIONAL_EXECUTABLES)
LOCAL_MODULE_TAGS := debug
LOCAL_C_INCLUDES += \
$(LOCAL_PATH)/../../../external/sqlite/dist \
$(LOCAL_PATH)/../../../external/sqlite/android
LOCAL_SHARED_LIBRARIES := \
libsqlite \
libsqlite3_android
include $(BUILD_EXECUTABLE)
here, in the source abc.c i'm trying to use the functions declared in sqlite3.h. When i'm trying to build the android source it is returning error
no rule libsqlite3_android.so to make target abc.so
i want to link the sqlite library to my source file.
Plz help me to find where i'm going wrong and how can i solve the problem.
First, make sure you have built SQLite3 before. (You should build the whole project before add any new stuff or customize any code)
Second, make sure you are build the same target product when you build the SQLite3. (Make sure you have select the correct menu when you do 'lunch').
Last, make sure the SQLite3 objects is in the target folders. YOURANDROIDROOT/out/target/PRODUCTNAME/system/symbols...
In fact, you shouldn't have to link with libsqlite3_android library.
According to the AOSP libsqlite makefile (external/sqlite/android/Android.mk), libsqlite3_android is a STATIC library which is included in the libsqlite dynamic library (external/sqlite/dist/Android.mk).
So linking with libsqlite should be enough.
I have the following situation,
I am porting a piece of an app using OpenSSL for AES encryption, I have everything compile, but the linker fails. The situation is the following:
1. I wrote a JNI wrapper that simply does :
private native String cipherString(String plainData, int datasize, String password, int passSize);
private native String decipherString(String cipheredData, int datasize, String password, int passSize);
next I have a c++ file which I call that has the proper JNI sintax which translates jstring to char * and all other needed transformations, and makes a call to another cpp file which actually imports openssl headers (present and accounted for) and calls openssl methods for ciphering and deciphering.
So when I call ndk-build, it builds all thumbs, so the compiler compiles them correctly.
next i needed to port openssl for android, and I used this OpenSSL for Android
which works like a char with a simple ndk-build (in the root of the project, ofcourse) and builds the libssl.so and libcrypto.so
So I need to connect the two.. I find it a challenge to connect the build scripts, so that one ndk-build compiles and linkes everything (I would appreciate a simple example project if someone has the time for it)
so I copied the compiled libssl and libcrypto .so files in jni/includes/prebuilt and want to include them in the project for the linker to be able to finally create the lib which I will use at the end.
I have the following Android.mk file
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
include $(LOCAL_PATH)/includes/build/common.mk
include $(LOCAL_PATH)/includes/build/common_includes.mk
APP_STL := gnustl_static
LOCAL_MODULE := packer
LOCAL_SRC_FILES := modules/cipher/wrapper.cpp \
... #rest of the cpp code
LOCAL_C_INCLUDES += $(LOCAL_PATH)/includes/openssl
LOCAL_SHARED_LIBRARIES := $(LOCAL_PATH)/includes/precompiled/libssl.so \
$(LOCAL_PATH)/includes/precompiled/libcrypto.so
LOCAL_SHARED_MODULES := sslx cryptox
include $(BUILD_SHARED_LIBRARY)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := sslx
LOCAL_SRC_FILES := $(LOCAL_PATH)/includes/precompiled/libssh.so
include $(PREBUILT_SHARED_LIBRARY)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := cryptox
LOCAL_SRC_FILES := $(LOCAL_PATH)/includes/precompiled/libssh.so
include $(PREBUILT_SHARED_LIBRARY)
And when calling ndk-build I get a dissapointing
sslx: LOCAL_SRC_FILES points to a missing file. Check that /home/user/Development/Tools/sdk/android/ndk/build/core//home/user/Development/Tools/sdk/android/ndk/build/core/includes/precompiled/libssh.so exists or that its path is correct. Aborting . Stop.
as you can already guess the path is totally wrong, and what confuses me is that ${LOCAL_PATH} returns correct path for the first batch of includes and a completely wrong one for the .so files ...
Any help would be really appreciated!
Here is the solution, updated to NDK8c
step zero: download and fix the Android NDK
I dunno how but the ndk has a very interesting flaw, which (in my oppinion) doesn't allow you to compile lot's of stuff, so to be able to compile OpenSSL you need to make a small fix, extract the ndk8c whereever you keep your tools, and then edit the file :
android-ndk-r8c/build/gmsl/__gmsl
line 512 :
change line
int_encode = $(__gmsl_tr1)$(wordlist 1,$1,$(__gmsl_input_int))
with line
int_encode = $(__gmsl_tr1)$(wordlist 1,$(words $1),$(__gmsl_input_int))
And you're good to go!
step one : Download OpenSSL and compile for Android :
either compile a ported version found here
or Download the official 1.0.0c version of OpenSSL and then compile it for android using the manual provided in the github I linked for the Android compatible version
So the next step is to get the libssl.so and libcrypto.so
and put the them in the NDK folder for easy access, so copy them from
openssl-folder/libs/armeabi/
to
android-ndk-r8c/platforms/android-8/arch-arm/usr/lib
this way when compiling you can include the libs using a simple linker switch -lssl -lcrypto
Step two : get Curl's latest source for here
Open the file in Docs/INSTALL and follow the steps needed to make the standalone toolchain and put in your desired folder, and then the tricky part, I needed to have android's source code for the config to continue, even though I have a standalone compiled openssl you can include the header files from there too, in anycase this is the more complicated version so you choose what you do, I did not choose to evade them so you can go to Google AOSP site and go trough the steps to build and initialize the environment.
so it would be something like :
1.download,
go to root of the source code and run :
~: build/envsetup.sh; lunch 1; make;
So finally we need to compile curl with SSL support, so,
Step three
extract curl to the desired folder
(I have a specific desire of disabling everything except http/s to keep the library as small as possible meaning about ~300k, if you want more protocols in your lib, remove the --disable-protocol for the desired protocol)
run the following :
make clean
export PATH=/opt/arm-linux-androideabi-4.4.3/bin:$PATH
export LDFLAGS="\
-lssl \
-lcrypto \
-L/home/user/Development/Tools/sdk/android/ndk/platforms/android-8/arch-arm/usr/lib"
export CFLAGS="\
-I/home/user/Development/AOSP/2.3.7/system/core/include \
-I/home/user/Development/Tools/sdk/android/ndk/platforms/android-8/arch-arm/usr/include"
./configure --host=arm-linux-androideabi \
--with-ssl=/home/user/Development/Projects/portingLibs/openssl-android-master \
--disable-ftp \
--disable-gopher \
--disable-file \
--disable-imap \
--disable-ldap \
--disable-ldaps \
--disable-pop3 \
--disable-proxy \
--disable-rtsp \
--disable-smtp \
--disable-telnet \
--disable-tftp \
--without-gnutls \
--without-libidn \
--without-librtmp \
--disable-dict
make
Note that in the block above, if you don't want to use the AOSP source, you could switch
-I/home/user/Development/AOSP/2.3.7/system/core/include \
with the include folder for your ssl distribution.
So finally you have :
static :
curl-7.28.1/lib/.libs/libcurl.a
and shared :
curl-7.28.1/lib/.libs/libcurl.so.5.3
So that's it.. take the file, and compile away :)
#Tancho
I made the change to line __gmsl:512 that you mentioned. Whilst it allowed OpenSSL to compile it also breaks the building of executables by $(BUILD_EXECUTABLE). Before the change my simple hello world application compiles and runs, but after the change it compiles but running it on my Nexus results in a seg fault.
Revert the change and all is well again. I don't know how to fix this, I don't really know what that line does, but this is just a little warning to anybody making that change.
I'm developing a cocos2d-x project, as its universal it works on android and iOS.
I recently added text to speech functionality using flite. In xcode all I do to use flite, is drag in the folder of the headers and c files into my xcode project, and then I can include its headers and use it. No problems there.
However in eclipse I can't get the compiler to see the files, and it keeps bombing out with the fatal error I mentioned. Specifically: fatal error: flite.h no such file or directory.
I've tried to include the folder in the includes section of eclipse under C/C++ general but no luck. I think this may have something to do with my android.mk file, guidance on how to set this up for this purpose would be greatly appreciated. On a side note, my project is set up so that my .cpp and .h files exist elsewhere on my computer and not in my actual project. Likewise for my flite source files. (I did try add them to my project however, out of desperation but the compiler still couldn't find them)
Thanks for your time.
PS: How does one refer to flite, is it a library/framework etc?
Edit
I tried to modify my Android.mk file, to locate the flite headers. My additions are indicated below
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := game_shared
LOCAL_MODULE_FILENAME := libgame
LOCAL_SRC_FILES := hellocpp/main.cpp \
../../Classes/AppDelegate.cpp \
../../Classes/HelloWorldScene.cpp \
../../Classes/CCLabelTTFExtension.cpp \
../../Classes/menuScene.cpp \
../../Classes/text_Parse.cpp \
../../Classes/FileTS.cpp
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../Classes/
#my addition
LOCAL_C_INCLUDES += $(LOCAL_PATH)/flite/
dirs := $(shell /flite -type d)
cfilestemp1 := $(shell find /src -type d)
cfilestemp2 := $(shell find $(cfilestemp1) -name *.c)
cfilestemp3 := $(sort $(cfilestemp2))
cfiles := $(subst $(LOCAL_PATH)/,,$(cfilestemp3))
LOCAL_SRC_FILES += \
$(cfiles)
#end my addition
LOCAL_WHOLE_STATIC_LIBRARIES := cocos2dx_static cocosdenshion_static cocos_extension_static
include $(BUILD_SHARED_LIBRARY)
$(call import-module,CocosDenshion/android) \
$(call import-module,cocos2dx) \
$(call import-module,extensions)
include $(CLEAR_VARS)
This got me closer, well, gave me different errors. Now the compiler complains of undefined references in my FileTS.cpp file, the file which is using flite in my project. (Note: My flite headers and source files are now added to my project in the jni folder)
The easiest way is to put all the source code into your Classes folder and list the cpp files in LOCAL_SRC_FILES like mainScene.cpp . this will make sure your library get build into your game object files.
I have the following situation,
I am porting a piece of an app using OpenSSL for AES encryption, I have everything compile, but the linker fails. The situation is the following:
1. I wrote a JNI wrapper that simply does :
private native String cipherString(String plainData, int datasize, String password, int passSize);
private native String decipherString(String cipheredData, int datasize, String password, int passSize);
next I have a c++ file which I call that has the proper JNI sintax which translates jstring to char * and all other needed transformations, and makes a call to another cpp file which actually imports openssl headers (present and accounted for) and calls openssl methods for ciphering and deciphering.
So when I call ndk-build, it builds all thumbs, so the compiler compiles them correctly.
next i needed to port openssl for android, and I used this OpenSSL for Android
which works like a char with a simple ndk-build (in the root of the project, ofcourse) and builds the libssl.so and libcrypto.so
So I need to connect the two.. I find it a challenge to connect the build scripts, so that one ndk-build compiles and linkes everything (I would appreciate a simple example project if someone has the time for it)
so I copied the compiled libssl and libcrypto .so files in jni/includes/prebuilt and want to include them in the project for the linker to be able to finally create the lib which I will use at the end.
I have the following Android.mk file
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
include $(LOCAL_PATH)/includes/build/common.mk
include $(LOCAL_PATH)/includes/build/common_includes.mk
APP_STL := gnustl_static
LOCAL_MODULE := packer
LOCAL_SRC_FILES := modules/cipher/wrapper.cpp \
... #rest of the cpp code
LOCAL_C_INCLUDES += $(LOCAL_PATH)/includes/openssl
LOCAL_SHARED_LIBRARIES := $(LOCAL_PATH)/includes/precompiled/libssl.so \
$(LOCAL_PATH)/includes/precompiled/libcrypto.so
LOCAL_SHARED_MODULES := sslx cryptox
include $(BUILD_SHARED_LIBRARY)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := sslx
LOCAL_SRC_FILES := $(LOCAL_PATH)/includes/precompiled/libssh.so
include $(PREBUILT_SHARED_LIBRARY)
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := cryptox
LOCAL_SRC_FILES := $(LOCAL_PATH)/includes/precompiled/libssh.so
include $(PREBUILT_SHARED_LIBRARY)
And when calling ndk-build I get a dissapointing
sslx: LOCAL_SRC_FILES points to a missing file. Check that /home/user/Development/Tools/sdk/android/ndk/build/core//home/user/Development/Tools/sdk/android/ndk/build/core/includes/precompiled/libssh.so exists or that its path is correct. Aborting . Stop.
as you can already guess the path is totally wrong, and what confuses me is that ${LOCAL_PATH} returns correct path for the first batch of includes and a completely wrong one for the .so files ...
Any help would be really appreciated!
Here is the solution, updated to NDK8c
step zero: download and fix the Android NDK
I dunno how but the ndk has a very interesting flaw, which (in my oppinion) doesn't allow you to compile lot's of stuff, so to be able to compile OpenSSL you need to make a small fix, extract the ndk8c whereever you keep your tools, and then edit the file :
android-ndk-r8c/build/gmsl/__gmsl
line 512 :
change line
int_encode = $(__gmsl_tr1)$(wordlist 1,$1,$(__gmsl_input_int))
with line
int_encode = $(__gmsl_tr1)$(wordlist 1,$(words $1),$(__gmsl_input_int))
And you're good to go!
step one : Download OpenSSL and compile for Android :
either compile a ported version found here
or Download the official 1.0.0c version of OpenSSL and then compile it for android using the manual provided in the github I linked for the Android compatible version
So the next step is to get the libssl.so and libcrypto.so
and put the them in the NDK folder for easy access, so copy them from
openssl-folder/libs/armeabi/
to
android-ndk-r8c/platforms/android-8/arch-arm/usr/lib
this way when compiling you can include the libs using a simple linker switch -lssl -lcrypto
Step two : get Curl's latest source for here
Open the file in Docs/INSTALL and follow the steps needed to make the standalone toolchain and put in your desired folder, and then the tricky part, I needed to have android's source code for the config to continue, even though I have a standalone compiled openssl you can include the header files from there too, in anycase this is the more complicated version so you choose what you do, I did not choose to evade them so you can go to Google AOSP site and go trough the steps to build and initialize the environment.
so it would be something like :
1.download,
go to root of the source code and run :
~: build/envsetup.sh; lunch 1; make;
So finally we need to compile curl with SSL support, so,
Step three
extract curl to the desired folder
(I have a specific desire of disabling everything except http/s to keep the library as small as possible meaning about ~300k, if you want more protocols in your lib, remove the --disable-protocol for the desired protocol)
run the following :
make clean
export PATH=/opt/arm-linux-androideabi-4.4.3/bin:$PATH
export LDFLAGS="\
-lssl \
-lcrypto \
-L/home/user/Development/Tools/sdk/android/ndk/platforms/android-8/arch-arm/usr/lib"
export CFLAGS="\
-I/home/user/Development/AOSP/2.3.7/system/core/include \
-I/home/user/Development/Tools/sdk/android/ndk/platforms/android-8/arch-arm/usr/include"
./configure --host=arm-linux-androideabi \
--with-ssl=/home/user/Development/Projects/portingLibs/openssl-android-master \
--disable-ftp \
--disable-gopher \
--disable-file \
--disable-imap \
--disable-ldap \
--disable-ldaps \
--disable-pop3 \
--disable-proxy \
--disable-rtsp \
--disable-smtp \
--disable-telnet \
--disable-tftp \
--without-gnutls \
--without-libidn \
--without-librtmp \
--disable-dict
make
Note that in the block above, if you don't want to use the AOSP source, you could switch
-I/home/user/Development/AOSP/2.3.7/system/core/include \
with the include folder for your ssl distribution.
So finally you have :
static :
curl-7.28.1/lib/.libs/libcurl.a
and shared :
curl-7.28.1/lib/.libs/libcurl.so.5.3
So that's it.. take the file, and compile away :)
#Tancho
I made the change to line __gmsl:512 that you mentioned. Whilst it allowed OpenSSL to compile it also breaks the building of executables by $(BUILD_EXECUTABLE). Before the change my simple hello world application compiles and runs, but after the change it compiles but running it on my Nexus results in a seg fault.
Revert the change and all is well again. I don't know how to fix this, I don't really know what that line does, but this is just a little warning to anybody making that change.