I'm getting the following error;
E/AndroidRuntime(446): Caused by: java.lang.UnsatisfiedLinkError: Library XYZ not found
but I have library XYZ in my project. The folder struct is:
-ProjectFolder
--obj
---local
----armeabi
-----objs
------libXYZ.so
------libstdc++.a
------XYZ
-------folderA
--------fileX.o
--------fileX.o.d
--jni
---Android.mk
---folderA
----fileX.cpp
----fileX.h
Android.mk file:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
APP_ABI := armeabi armeabi-v7a x86
LOCAL_MODULE := XYZ
LOCAL_SRC_FILES := folderA/fileX.cpp
include $(BUILD_SHARED_LIBRARY)
C++ compile output:
Compile++ thumb : XYZ <= fileX.cpp
In file included from jni/folderA/fileX.h:1:0,
from jni/folderA/fileX.cpp:1:
/Applications/android-ndk-r8b/platforms/android-5/arch-arm/usr/include/jni.h:592:13: note: the mangling of 'va_list' has changed in GCC 4.4
StaticLibrary : libstdc++.a
SharedLibrary : libXYZ.so
Install : libXYZ.so => libs/armeabi/libXYZ.so
I don't understand why the error says "Library XYZ not found", when the library is in the correct place.
Related
I am struggling with this problem since few weeks I hope someone can help me.
I have created a C function wrapper in my Android app that impements the JNI export. I have also created a second .so library in order to call my original library but here I have a problem when linking with ndk-build. This is my code:
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := my_prebuilt_lib
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../jni/
LOCAL_SRC_FILES := ../jniLibs/$(TARGET_ARCH_ABI)/my_prebuilt_lib.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := myjni
LOCAL_SRC_FILES := wrapper.cpp
LOCAL_SHARED_LIBRARY += my_prebuilt_lib
include $(BUILD_SHARED_LIBRARY)
This is the command I am using to build myjni.so:
ndk-build NDK_PROJECT_PATH=./ NDK_APPLICATION_MK=./jni/Application.mk
And I get this error:
Android NDK: WARNING: APP_PLATFORM android-16 is higher than android:minSdkVersion 1 in .//AndroidManifest.xml. NDK binaries will *not* be compatible with devices older than android-16. See https://android.googlesource.com/platform/ndk/+/master/docs/user/common_problems.md for more information.
[armeabi-v7a] Install : my_prebuilt_lib.so => libs/armeabi-v7a/liblocSDK4d.so
[armeabi-v7a] Compile++ thumb: myjni <= wrapper.cpp
[armeabi-v7a] SharedLibrary : libmyjni.so
jni/wrapper.cpp:24: error: undefined reference to 'hex2int(char)'
clang++: error: linker command failed with exit code 1 (use -v to see invocation)
Looking into my_prebuilt_lib.so I can see the following declaration about the function I want to call:
00004c51 T hex2int(char)
Any suggestion?
I am trying to interface with an MSI SDR dongle, using an android app
This device is a clone of the SDRPlay SDR device, and is compatible with it's software and drivers
I am trying to interface with this using an OTG cable and android phone
The android drivers for this can be downloaded from here https://www.sdrplay.com/downloads/
It is in the Android tab under the API/HW – V2.11 (15TH NOV 2017) link (https://www.sdrplay.com/anddl.php)
A possible sample code for this driver can be found here: https://www.sdrplay.com/docs/AndroidIntegrationNote.pdf
Before making the full android program it says the library (libmir_sdr_api.a) should be built into an .so library file using ndk-build
I currently have Android's hello-jni sample project from here: https://github.com/android/ndk-samples/tree/android-mk/hello-jni
I have replaced the jni folder using the Android.mk file, libmir_sdr_api.a, mir_sdr.h, initialization-jni.cpp, demod-jni.cpp and demod-jni.h files mentioned in section 3 of the AndroidIntegrationNote.pdf file I linked above
When I execute ndk-build from the hello-jni project folder, I get he following error:
Android NDK: Found platform level in ./default.properties. Setting APP_PLATFORM to android-25.
Android NDK: android-25 is an alias for android-24. Adjusting APP_PLATFORM to match.
[arm64-v8a] Gdbserver : [aarch64-linux-android] libs/arm64-v8a/gdbserver
[arm64-v8a] Gdbsetup : libs/arm64-v8a/gdb.setup
[x86_64] Gdbserver : [x86_64-linux-android] libs/x86_64/gdbserver
[x86_64] Gdbsetup : libs/x86_64/gdb.setup
[armeabi-v7a] Gdbserver : [arm-linux-androideabi] libs/armeabi-v7a/gdbserver
[armeabi-v7a] Gdbsetup : libs/armeabi-v7a/gdb.setup
[x86] Gdbserver : [i686-linux-android] libs/x86/gdbserver
[x86] Gdbsetup : libs/x86/gdb.setup
make: *** No rule to make target 'jni/initialisation-jni.cpp', needed by 'obj/local/arm64-v8a/objs-debug/mirics-jni/initialisation-jni.o'. Stop.
I am used to compiling NDK code suing Android Studio and cmake so I am not sure what is going on here. I have not been able to link the .a file through cmake either so I thought of giving the driver manufacturer's sample code a try, but it not working either. Is the Android.mk file in pdf file linked earlier incomplete, or am I not building it correctly? These are the contents of the Android.mk file:
# $(call my-dir) returns the local directory which is the jni directory
LOCAL_PATH := $(call my-dir)
# libmir_sdr_api.a – this section creates a version of the Mirics API to be used below
include $(CLEAR_VARS)
LOCAL_MODULE := mir_sdr_api-prebuilt
LOCAL_SRC_FILES := libmir_sdr_api.a
LOCAL_EXPORT_C_INCLUDES := $(call my-dir)
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
# mirics-jni – this section uses the jni C++ source code to build the dynamic library
LOCAL_MODULE := mirics-jni
LOCAL_SRC_FILES := initialisation-jni.cpp demod-jni.cpp
LOCAL_C_INCLUDES := $(call my-dir)
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib
LOCAL_STATIC_LIBRARIES := mir_sdr_api-prebuilt
include $(BUILD_SHARED_LIBRARY)
Regarding missing jni/initialisation-jni.cpp, you probably have the file jni/initialization-jni.cpp instead.
Also, unfortunately, the document is wrong. You can only use $(call my-dir) easily at the top of the file. Luckily, Android NDK adds the jni directory to includes path for you. Still, to be on the safe side, better write:
# $(call my-dir) returns the local directory which is the jni directory
LOCAL_PATH := $(call my-dir)
# libmir_sdr_api.a – this section creates a version of the Mirics API to be used below
include $(CLEAR_VARS)
LOCAL_MODULE := mir_sdr_api-prebuilt
LOCAL_SRC_FILES := libmir_sdr_api.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
# mirics-jni – this section uses the jni C++ source code to build the dynamic library
LOCAL_MODULE := mirics-jni
LOCAL_SRC_FILES := initialization-jni.cpp demod-jni.cpp
LOCAL_C_INCLUDES := $(LOCAL_PATH)
LOCAL_LDLIBS := -L$(SYSROOT)/usr/lib
LOCAL_STATIC_LIBRARIES := mir_sdr_api-prebuilt
include $(BUILD_SHARED_LIBRARY)
Finally, pay attention to your build process. You only have one kind of the libmir_sdr_api.a static library, it's built for a 32-bit ARM CPU. Therefore you cannot build your libmirics-jni.so for other architectures. Add
APP_ABIS = armeabi-v7a
to your Application.mk file, or specify
abifilters = armeabi-v7a
in your build.gradle, if you build your library in Android Studio.
I am having a hard time in integrating dlib with my android studio NDK project, Basically I want to use the library in my native C++ code, I am not sure about the standard way of doing the same, I have my Android.mk file which is under app/src/main/jni as :
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := dlib
LOCAL_SRC_FILES := dlib/all/source.cpp
LOCAL_CPPFLAGS = -I/opt/X11/include
include $(BUILD_STATIC_LIBRARY)
include $(CLEAR_VARS)
OPENCVROOT:= /Users/anmoluppal/Downloads/OpenCV-android-sdk
OPENCV_CAMERA_MODULES:=on
OPENCV_INSTALL_MODULES:=on
OPENCV_LIB_TYPE:=SHARED
include ${OPENCVROOT}/sdk/native/jni/OpenCV.mk
LOCAL_MODULE := ndkDemo
LOCAL_STATIC_LIBRARIES := dlib
LOCAL_SRC_FILES := main.cpp face_detector.cpp face_tracker.cpp ft_data.cpp patch_model.cpp shape_model.cpp
include $(BUILD_SHARED_LIBRARY)
And the Application.mk file looks something like:
APP_STL := gnustl_static
APP_CPPFLAGS += -fexceptions -frtti
APP_ABI := all
And the project structure is:
+ app
---+ src
-----+ main
-------+ jni
---------+ dlib
---------+ Application.mk
---------+ Android.mk
---------+ (... Other .cpp files)
And I am getting a lot of undefined reference to errors which are referring to X11 library on Mac, which is indeed installed properly, I want to know if this is the correct way of including a library in NDK project? Or alternatively I need to create a Android.mk file in dlib folder as well? Also I am unaware of the main .cpp files which are required as LOCAL_SRC_FILES for the .mk file.
After ndk-build I get the following output:
[arm64-v8a] Compile++ : ndkDemo <= main.cpp
[arm64-v8a] Compile++ : ndkDemo <= face_detector.cpp
[arm64-v8a] Compile++ : ndkDemo <= face_tracker.cpp
[arm64-v8a] Compile++ : ndkDemo <= ft_data.cpp
[arm64-v8a] Compile++ : ndkDemo <= patch_model.cpp
[arm64-v8a] Compile++ : ndkDemo <= shape_model.cpp
[arm64-v8a] Compile++ : dlib <= source.cpp
[arm64-v8a] StaticLibrary : libdlib.a
[arm64-v8a] SharedLibrary : libndkDemo.so
There are several things you need to consider.
First: The libraries you link need to be cross compiled for the respective ABIs. Your Application.mk says all so you need to provide all (arm, x86, MIPS,...). Are your libraries prebuilt? In that case you will need to cross compile them manually.
You are missing the include directories for your libraries. You can include them with :
LOCAL_EXPORT_C_INCLUDES
LOCAL_C_INCLUDES
This is the way to go instead of using CPP-Flags.
There are some other problems in your makefile which you should resolve by inspecting makefiles of other people on stackoverflow or search in the NDK documentation. For example I dont think that you can provide the LOCAL_SRC_FILES like you did, you need to separate them by backslashes like that:
LOCAL_SRC_FILES := \ x.cpp \ y.cpp
Your project structure is fine, I think you are almost there.
Feel free to provide the new version of your makefiles when you resolved the linking errors.
I'm trying to use openssl within android ndk.
I've used openssl source code from guardianproject github page, which is able to produce libssl.so and libcrypto.so files.
Currently I'm stuck at linking those 2 files with my jni interface c file.
Below is my Android.mk file, my jni interface c file called "security.c"
LOCAL_PATH := $(call my-dir)
# Prebuilt libssl
include $(CLEAR_VARS)
LOCAL_MODULE := ssl
LOCAL_SRC_FILES := libprebuilt/libssl.so
include $(PREBUILT_SHARED_LIBRARY)
# Prebuilt libcrypto
include $(CLEAR_VARS)
LOCAL_MODULE := crypto
LOCAL_SRC_FILES := libprebuilt/libcrypto.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := security
LOCAL_SRC_FILES := security.c
LOCAL_SHARED_LIBRARIES= ssl crypto
include $(BUILD_SHARED_LIBRARY)
And this is my security.c file
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <jni.h>
#include "openssl/bio.h"
#include "openssl/ssl.h"
#include "openssl/err.h"
jstring Java_com_test_stringFromJNI(JNIEnv* env, jobject thiz) {
SSL_load_error_strings();
ERR_load_BIO_strings();
OpenSSL_add_all_algorithms();
return (*env)->NewStringUTF(env, "Hello from JNI");
}
When build with ndk-build, this error occured
Android NDK: WARNING: APP_PLATFORM android-19 is larger than android:minSdkVersion 8 in /Users/huydo/cur-project/company/kimisaki_native/android_os/ensemble_girls/AndroidManifest.xml
[armeabi-v7a] Install : libcrypto.so => libs/armeabi-v7a/libcrypto.so
[armeabi-v7a] Compile thumb : security <= security.c
[armeabi-v7a] SharedLibrary : libsecurity.so
[armeabi-v7a] Install : libsecurity.so => libs/armeabi-v7a/libsecurity.so
[armeabi-v7a] Install : libssl.so => libs/armeabi-v7a/libssl.so
[armeabi] Install : libcrypto.so => libs/armeabi/libcrypto.so
[armeabi] Compile thumb : security <= security.c
[armeabi] SharedLibrary : libsecurity.so
[armeabi] Install : libsecurity.so => libs/armeabi/libsecurity.so
[armeabi] Install : libssl.so => libs/armeabi/libssl.so
[x86] Install : libcrypto.so => libs/x86/libcrypto.so
/Users/huydo/android-ndk-r9d/toolchains/x86-4.6/prebuilt/darwin-x86_64/bin/i686-linux-android-strip: Unable to recognise the format of the input file `/Users/huydo/cur-project/XXX/android_os/YYY/libs/x86/libcrypto.so'
make: *** [/Users/huydo/cur-project/XXX/android_os/YYY/libs/x86/libcrypto.so] Error 1
make: *** Deleting file `/Users/huydo/cur-project/XXX/android_os/YYY/libs/x86/libcrypto.so'
Noted that libssl.so and libcrypto.so has been correctly copied into armeabi and armeabi-v7a. It stucked when building for mips and x86 architecture.
If you experienced this error before, can you give me a glue what happened.
You're using the same ARM libssl.so and libcrypto.so when compiling for every architecture, which can't work.
You need to use prebuilts targeting the right architectures. For this you can create subfolders inside libprebuilt named against each architecture (armeabi, armeabi-v7a, x86, mips), add your prebuilts .so files under each of these, and use $(TARGET_ARCH_ABI) inside your Android.mk to reference your .so files:
LOCAL_PATH := $(call my-dir)
# Prebuilt libssl
include $(CLEAR_VARS)
LOCAL_MODULE := ssl
LOCAL_SRC_FILES := libprebuilt/$(TARGET_ARCH_ABI)/libssl.so
include $(PREBUILT_SHARED_LIBRARY)
# Prebuilt libcrypto
include $(CLEAR_VARS)
LOCAL_MODULE := crypto
LOCAL_SRC_FILES := libprebuilt/$(TARGET_ARCH_ABI)/libcrypto.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := security
LOCAL_SRC_FILES := security.c
LOCAL_SHARED_LIBRARIES= ssl crypto
include $(BUILD_SHARED_LIBRARY)
If you don't find x86 versions of libssl.so and libcrypto.so, you can pull these out from the x86 emulator.
To specify against which architecture you want to compile your projet, use APP_ABI variable inside Application.mk, for example :
APP_ABI := armeabi-v7a x86 mips
i try to use freetype lib in my project with cocos2d-x. I built freetype and added to the project(like here http://en.wikibooks.org/wiki/OpenGL_Programming/Installation/Android_NDK#FreeType ). In xcode it builds without errors. Now I trying to use it on android. I made make file in freetype dir:
LOCAL_PATH:= $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := freetype
LOCAL_SRC_FILES := lib/libfreetype.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/include $(LOCAL_PATH)/include/freetype2
include $(PREBUILT_STATIC_LIBRARY)
and added to main makefile
LOCAL_STATIC_LIBRARIES := freetype curl_static_prebuilt
...
$(call import-module,freetype)
during linking has the error: libfreetype.a: file format not recognized; treating as linker script
Prebuilt : libfreetype.a <=
/Users/user/Development/Slots/Slots_Android/lib/freetype/lib/
SharedLibrary : libgame.so
/Users/user/Development/android_ndk_r8b/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86/bin/../lib/gcc/arm-linux-androideabi/4.6.x-google/../../../../arm-linux-androideabi/bin/ld:./obj/local/armeabi/libfreetype.a:
file format not recognized; treating as linker script
/Users/user/Development/android_ndk_r8b/toolchains/arm-linux-androideabi-4.6/prebuilt/darwin-x86/bin/../lib/gcc/arm-linux-androideabi/4.6.x-google/../../../../arm-linux-androideabi/bin/ld:./obj/local/armeabi/libfreetype.a:1:
syntax error collect2: ld returned 1 exit status
How to fix it?