I want to use the RSA of openssl, so I need integrate openssl to Android with ndk.I download the source of openssl for Android at https://github.com/aluvalasuman/OpenSSL1.0.1cForAndroid.
ndk-build in the source folder generated libcrypto.so and libssl.so, I copied them to $(MY_PROJECT)/jni/lib/, then linked them in Android.mk like that:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_C_INCLUDES := $(LOCAL_PATH)/include
LOCAL_LIBS := $(LOCAL_PATH)/lib
LOCAL_STATIC_LIBRARIES := libcrypto libssl
LOCAL_LDLIBS := -llog
LOCAL_MODULE := jni
LOCAL_SRC_FILES := jni.c
include $(BUILD_SHARED_LIBRARY)
And tested the openssl like that:
#include <stdio.h>
#include <string.h>
#include <openssl/rsa.h>
#define nr_bits 2048
int test_openssl()
{
RSA *rsa = RSA_generate_key(nr_bits, 65537, NULL, NULL);
return 0;
}
When I compile it , it threw the error:
....jni/license/license.c:10: error: undefined reference to 'RSA_generate_key'
collect2: ld returned 1 exit status
Does anyone know what's the problem? I will be very grateful if anyone could help.
Such undefined reference errors typically indicate that the compiler/linker did not find libcrypto.so in it's path. You could try a couple of things:
Add -lcrypto to LOCAL_LDLIBS. This tells the compiler to use libcrypto.so, if possible, to resolve undefined symbols
Add $(MY_PROJECT)/jni/lib/ to LOCAL_LIBS so the compiler knows where to pick -lcrypto from. This assumes that $(MY_PROJECT) is defined in the make file.
I know this is an old question, but if someone is experiencing this problem, she or he could solve the problem by using:
LOCAL_STATIC_LIBRARIES := crypto
instead of
LOCAL_STATIC_LIBRARIES := libcrypto libssl
Related
I have come across a problem with trying to compile cURL with SSL support into an app.
So far, I have successfully compiled the openSSL package into libcrypt.so and libssl.so.
I believe I have successfully compiled a version of libcurl.a with SSL support using the configure script and running it through the cross-chain compiler found in the NDK (under a linux environment).
Now, I am attempting to write a .so library under Eclipse that can be called by the Java code of an Android App.
Here is the file structure so far:
Project Folder ---> jni ---> include ---> curl ---> curl headers
| |
| -> openssl ---> ssl and crypto headers
|
-> libcrypto.so
-> libssl.so
-> libcurl.a
-> jniProcessRequest.c
-> Android.mk
Android.mk reads:
LOCAL_PATH := $(call my-dir)
MY_PATH := $(LOCAL_PATH)
include $(CLEAR_VARS)
LOCAL_PATH := $(MY_PATH)
LOCAL_MODULE := crypto
LOCAL_SRC_FILES := libcrypto.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/openssl/
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := ssl
LOCAL_SRC_FILES := libssl.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/openssl/
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := curl
LOCAL_SRC_FILES := libcurl.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/curl/
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := JNIProcessRequest
LOCAL_SRC_FILES := JNIProcessRequest.c
LOCAL_SHARED_LIBRARIES := crypto ssl
LOCAL_STATIC_LIBRARIES := curl
LOCAL_LDLIBS := -llog
include $(BUILD_SHARED_LIBRARY)
jniProcessRequest.c:
#include <jni.h>
#include <stdlib.h>
#include "include/curl/curl.h"
#include <android/log.h>
JNIEXPORT void JNICALL Java_com_example_jniprocessrequest_MainActivity_jniProcessRequest(JNIEnv * env, jobject obje){
CURL *conn;
conn = curl_easy_init();
}
Every time I attempt to compile the above, I have undefined reference errors in Eclipse:
make: *** [obj/local/armeabi/libJNIProcessRequest.so] Error 1
undefined reference to 'curl_easy_init'
I am thinking this is some sort of linkage error but am struggling to find where the error is occurring. I have spent nearly two days trying all different methods of placing the shared libraries in differing places, switching the static libcurl with a shared libcurl, altering the Android.mk file and following tutorials on how to get cURL working in Android.
Any help would be greatly appreciated!
I believe that the problem was stemming from an incorrectly built libcurl.a static library. I replaced my library with one that was compiled by a user on GitHub and without changing any code, the linkage errors disappeared.
You use curl as a prebuilt module.
As stated by the NDK documentation you should take care to wrap it under include $(CLEAR_VARS) and (most importantly) include $(PREBUILT_STATIC_LIBRARY) directives as follow:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := foo-prebuilt
LOCAL_SRC_FILES := libfoo.a
include $(PREBUILT_STATIC_LIBRARY)
Right after take care to wrap your JNIProcessRequest module with include $(CLEAR_VARS) and include $(BUILD_SHARED_LIBRARY).
For more details please refer to the docs/PREBUILTS.html section that you can find within your Android NDK folder (it looks like this).
I'm trying to use the fftw3 library on Android, with float precision enabled.
I've compiled the fftw3 source code as it is explained in this question.
I added the "--enable-float" as mentioned here.
So i've created the fftw libraries and placed them into another Android project. I integrated them, so that i can use the library.
When i use the double methods of fftw everything works fine. But:
I tried to use the float methods of fftw, but if i try to this i get these errors:
Install : libfftw3.so => libs/armeabi/libfftw3.so
Compile thumb : hello-jni <= hello-jni.c
jni/hello-jni.c: In function 'dst_test':
jni/hello-jni.c:85:15: warning: assignment from incompatible pointer type [enabled by default]
SharedLibrary : libhello-jni.so
/opt/android-ndk/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86_64/bin/../lib/gcc/arm-linux-androideabi/4.6/../../../../arm-linux-androideabi/bin/ld: ./obj/local/armeabi/objs/hello-jni/hello-jni.o: in function dst_test:jni/hello-jni.c:85: error: undefined reference to 'fftwf_plan_r2r_1d'
collect2: ld returned 1 exit status
make: *** [obj/local/armeabi/libhello-jni.so] Error 1
My guess is, that i have done something wrong, when i integrated the library.
I did a
#include "api/fftw3.h"
in my c-File.
My Android.mk looks like this:
LOCAL_PATH := $(call my-dir)
# Prebuilt FFTW library
include $(CLEAR_VARS)
LOCAL_MODULE := fftw3
LOCAL_SRC_FILES := libfftw3.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := hello-jni
LOCAL_SRC_FILES += hello-jni.c
LOCAL_SHARED_LIBRARIES := fftw3
LOCAL_LDLIBS := -llog
include $(BUILD_SHARED_LIBRARY)
There are some fftw + android tutorial on the internet, but i couldn't find anything about integrating the "float version" of it.
I am actually having a problem with FFTW3 as well, but slightly different. I think the answer to your question lies in the building the package with float support. Adding --enable-float to your ./configure command should do the trick. After it's built, you can include it the same way that you're including fftw3, just make it fftw3f.
Good luck.
I with success compile library LibXtract to shared object libxtract.so and want to use is in second project.
In mention project I try to compile it on simple function:
#include <com_androidnative1_NativeClass.h>
#include <android/log.h>
#include "libxtract.h"
JNIEXPORT void JNICALL Java_com_androidnative1_NativeClass_showText
(JNIEnv *env, jclass clazz)
{
float mean = 0, vector[] = {.1, .2, .3, .4, -.5, -.4, -.3, -.2, -.1}, spectrum[10];
int n, N = 9;
float argf[4];
argf[0] = 8000.f;
argf[1] = XTRACT_MAGNITUDE_SPECTRUM;
argf[2] = 0.f;
argf[3] = 0.f;
xtract[XTRACT_MEAN]((void *)&vector, N, 0, (void *)&mean);
__android_log_print(ANDROID_LOG_DEBUG, "LIbXtract", "Button pushe2");
}
I have flat structure:
jni/com_androidnative1_NativeClass.c
jni/com_androidnative1_NativeClass.hjni/libxtract.h
jni/other *.h files from libxtract interface
jni/Android.mk
jni/Applicatoin.mk
library libxtract.so I put in mainproject/lib folder
my Android.mk file looks like:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_SRC_FILES := com_androidnative1_NativeClass.c
LOCAL_MODULE := com_androidnative1_NativeClass
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/
LOCAL_LDLIBS += -llog
LOCAL_SHARE_LIBRARIES := libxtract
NDK_MODULE_PATH += $(LOCAL_PATH)/../lib/
include $(BUILD_SHARED_LIBRARY)
and I still got error:
Compile thumb : com_androidnative1_NativeClass <= com_androidnative1_NativeClass.c
SharedLibrary : libcom_androidnative1_NativeClass.so./obj/local/armeabi/objs/com_androidnative1_NativeClass/com_androidnative1_Nativ eClass.o: In function `Java_com_androidnative1_NativeClass_showText':
/home/jack/Projects/AndroidNative1/jni/com_androidnative1_NativeClass.c:20: undefined reference to `xtract'
collect2: ld returned 1 exit status
make: *** [obj/local/armeabi/libcom_androidnative1_NativeClass.so] Error 1
Code came form example of LibXtract and under C++ compile without problems, any ideas?
Your Android make file should be ...
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LIB_PATH := $(LOCAL_PATH)/../lib
LOCAL_SRC_FILES := com_androidnative1_NativeClass.c
LOCAL_MODULE := com_androidnative1_NativeClass
LOCAL_LDLIBS += -llog
LOCAL_LDLIBS += $(LIB_PATH) -lxtract
LOCAL_SHARE_LIBRARIES := libxtract
include $(BUILD_SHARED_LIBRARY)
Try this make file in your second project, and you can successfully build your code without having any error.
In the above answer all is right but exept one.
When we want to link lib we must add -L before LOCAL_LDLIBS dir as below.
LIB_PATH := $(LOCAL_PATH)/../lib
LOCAL_LDLIBS += **-L**$(LIB_PATH) -lxtract
Else it will give error as below
cannot open XXX/../lib: Permission denied
You need to tell Android NDK build scripts about your shared library. Check ${NDK}/doc/PREBUILTS.html for instructions how this can be done. They advise to add Android.mk in the same directory where you have your libXtract.so:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libXtract
LOCAL_SRC_FILES := libXtract.so
include $(PREBUILT_SHARED_LIBRARY)
Debugging tip: I guess you are using ndk-build to build your "second project". Try running ndk-build with V=99 (try V=99 ndk-build or ndk-build V=99 - my memory failing). This will show you the the exact failing linking command. You should likely have options -lXtract and -L/path/to/libXtract/library. (Sometimes it is convenient to just copy and paste the linking command to run it manually to find the right options for successful linking, before actually fixing the build settings.)
Update: I now see #codetiger's comment seems to point to a same sort of answer (without mentioning the NDK document which is good reading - so I am not deleting this answer).
I have the latest android ndk installed. I am using Eclipse along with Sequoyah.
I am trying to use various things that should be found in stlport or gnustl libraries, but I keep getting errors that they cannot be found.
In JNI/Application.mk I only have
APP_STL := stlport_shared
I have tried stlport_static and the gnustl_static/shared and all get the same result.
In my Android.mk I have
LIB_TEST_DIR := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_PATH := $(LIB_TEST_DIR)
LOCAL_MODULE := testmod
LOCAL_MODULE_FILENAME := libtestmod
LOCAL_CPP_EXTENSION := .cxx .cpp .cc
LOCAL_C_INCLUDES := $(LOCAL_PATH)/libtest2/
LOCAL_CFLAGS := -DHAVE_CONFIG_H
LOCAL_SRC_FILES := test.cc
include $(BUILD_SHARED_LIBRARY)
In a header file that test.cc includes, I have
#include <cassert>
#include <algorithm>
#include <iosfwd>
But, when I build, it cannot find any of these. Any idea what I am doing wrong?
When I do a clean, I see this:
Clean: addiJNI [armeabi]
Clean: stlport_shared [armeabi]
Clean: stlport_static [armeabi]
So, it seems like it knew I wanted stlport. Similar thing happens if I use the gnu libs instead. But when I build even the simplest example, I get something like...
jni/test.cpp:4:19: error: cassert: No such file or directory
jni/test.cpp:6:21: error: algorithm: No such file or directory
jni/test.cpp:7:18: error: iosfwd: No such file or directory
make: *** [obj/local/armeabi/objs/addiJNI/addiJNI.o] Error 1
This was the problem, not sure why.
LOCAL_CPP_EXTENSION := .cxx .cpp .cc
It didn't like the .cxx at the beginning.
I am trying to build an android application that uses static libraries from some existing c++ code. However I cannot seem to get things building, here are the steps I have taken so far..
I have ndk-r5b and have built the standalone toolchain as per ndk/docs/STANDALINE-TOOLCHAIN.html. I have then used the standalone toolchain compiler (arm-linux-androideabi-g++) instead of g++ for the CXX flag in the Makefile that compiles the static libraries I need. This compiles without errors and there are 3 static libraries produced.
Here is a code snippet of some of the flags used to build the prebuilt libraries:
CXX = arm-linux-androideabi-g++
SYSTEM_LIBS = -lstdc++ -lm
INCLUDE_PATH += ${NDK_PATH}/platforms/android-8/arch-arm/usr/include/
Here is a sample line that is produced from the makefile when compiling:
arm-linux-androideabi-g++ -c -DTIME_SIM -I./include -I/home/greg/dev/Android/android-ndk-r5b/platforms/android-8/arch-arm/usr/include/ -fpic -ggdb3 -SimTime.C -o SimTime.o
Next I build the app using ndk-build using the following for Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := engine
LOCAL_SRC_FILES := ../libs/libEngine.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := shmem
LOCAL_SRC_FILES := ../libs/libShMem.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := util
LOCAL_SRC_FILES := ../libs/libUtil.a
include $(PREBUILT_STATIC_LIBRARY)
# build server as a shared library
include $(CLEAR_VARS)
LOCAL_MODULE := libServer
LOCAL_C_INCLUDES := $(LOCAL_PATH)/../../include
LOCAL_SRC_FILES := \
Server.C \
Router.C \
RouterMsgs.C \
Federation.C \
cripName.C \
ver.C \
JNIWrapper.cpp
LOCAL_STATIC_LIBRARIES := engine shmem util
include $(BUILD_SHARED_LIBRARY)
The prebuilt libraries compile fine using the standalone toolchain compiler given in the android ndk. However there are many unresolved references to ostream when linking the shared library to the prebuilt libraries using ndk-build. For exampe:
/home/android/obj/local/armeabi/libShMem.a(SubscriptionItem.o): In function `SUBSCRIPTION_ITEM::Print(std::basic_ostream<char, std::char_traits<char> >&)':/home/src/comm/SubscriptionItem.C:97: undefined reference to `std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*)'
I assume I am missing some important flags or not doing something correct when I am compiling using the standalone compiler but any help or insight on this issue would be greatly appreciated as I cant seem to find this answer on google or in any of the android ndk docs. Thanks!
Well, you can actually fix that with creating a Application.mk file inside the same folder as the Android.mk file is, containing:
APP_STL := stlport_static
for using the static stlport that is located inside the Android NDK.
I had the same issue and resolved it by adding a module for the standard C++ library. The library linked by the ndk-build system is from the wrong location (platforms/android-9/arch-arm/usr/lib in my case).
include $(CLEAR_VARS)
LOCAL_MODULE := rightstdc
LOCAL_SRC_FILES := <path to the correct libstdc++.a>
include $(PREBUILT_STATIC_LIBRARY)
Add the module tag to the list of static libraries:
LOCAL_STATIC_LIBRARIES := engine shmem util rightstdc
The build/core/build-binary.mk prepends -L$(SYSROOT)/usr/lib if any libraries are specified in LOCAL_LDLIBS but in my case that is the wrong path.
I don't know if there is a missing step that should copy the correct libstdc++ to that location but the approach above will work.