How do I make ndk-build create executable named like a library? - android

I want my native executable to be auto-populated to /data/data/.../lib/. For this it is to be named like lib*.so. But if I try to set this name, Android NDK complains:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libhello.so
LOCAL_SRC_FILES := hello.c
include $(BUILD_EXECUTABLE)
Android NDK: jni/Android.mk:hello.so: LOCAL_MODULE_FILENAME must not contain a file extension

A workaround: install with a name Android NDK wants, then rename after installation:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := hello
LOCAL_SRC_FILES := hello.c
include $(BUILD_EXECUTABLE)
all:
mv ${NDK_APP_DST_DIR}/hello ${NDK_APP_DST_DIR}/libhello.so
And your application can call the executable /data/data/<package>/lib/libhello.so without any preparatory steps.

You are trying to build an executable instead of a shared library. You want to change this:
include $(BUILD_EXECUTABLE)
to this:
include $(BUILD_SHARED_LIBRARY)

Related

ndk-build undefined reference errror

I'm using ndk-build to build a set of shared library(.so) for my android project. I configured and made the source code of C++ library(gdal-2.2.2).
everything was ok.("./configure & make & make install" was successful).
So i created my jni folder like this documentation.
but when I'm trying to use ndk-build on windows, I get a lot of error like "Undefined refrence to somthing".
I've spent a lot of time on this project. Is there someone to help me?
Thanks.
Update
I used configure like this on ubuntu 16.04:
./configure --prefix=/home/mahdi/Desktop/build/ --with-spatialite=yes --with-spatialite-soname=libspatialite.so --host=i686-linux-android CXXFLAGS="-D_GLIBCXX_USE_CXX11_ABI=0" LIBS="-lsupc++ -lstdc++"
After make & make install step I created JNI. this is my directory.
jniwrap
jni
gdal
Android.mk
Application.mk
gdal_wrap.cpp
gdalconst_wrap.c
gnm_wrap.cpp
libgdal.a
ogr_wrap.cpp
osr_wrap.cpp
Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := gdal
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/gdal/include
LOCAL_SRC_FILES := libgdal.a
LOCAL_EXPORT_LDLIBS := -lz
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := gdaljni
LOCAL_SRC_FILES := gdal_wrap.cpp
LOCAL_STATIC_LIBRARIES := gdal
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := gdalconstjni
LOCAL_SRC_FILES := gdalconst_wrap.c
LOCAL_STATIC_LIBRARIES := gdal
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := ogrjni
LOCAL_SRC_FILES := ogr_wrap.cpp
LOCAL_STATIC_LIBRARIES := gdal
include $(BUILD_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := osrjni
LOCAL_SRC_FILES := osr_wrap.cpp
LOCAL_STATIC_LIBRARIES := gdal
include $(BUILD_SHARED_LIBRARY)
Aplication.mk
APP_STL := gnustl_shared
APP_CFLAGS := Android.mk
APP_ABI := x86
APP_PLATFORM := android-14
Then I used android-ndk-r16b in windows-x86_64 but I faced with these errors like this picture:
There was a lot of "undefined reference error" that i can't show here.
Note: for making gdal Java Binding I used swig and jdk7 on my ubuntu 16.04.
When you build libgdal.a on your ubuntu machine, you must have sqlite3, which resolves #include "sqlite3.h".
These include files are enough for a static library, but to create libgdaljni.so you also need libsqlite3.a. You can cross-compile it for Android it yourself on the same ubuntu machine, but it is probably OK to get prebuilt library e.g. from https://github.com/couchbase/couchbase-lite-java-native/tree/master/vendor/sqlite/libs/android.
Copy this file (for appropriate ABI) to the same directory, and modify your Android.mk accordingly:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := sqlite3
LOCAL_SRC_FILES := libsqlite3.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := gdal
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/gdal/include
LOCAL_SRC_FILES := libgdal.a
LOCAL_EXPORT_LDLIBS := -lz
LOCAL_STATIC_LIBRARIES := sqlite3
include $(PREBUILT_STATIC_LIBRARY)
*continued without changes*
If you still have "undefined reference error", this could mean that some other libraries should be added.

$(LOCAL_PATH) not returning the path to current directory correctly

I am using Android NDK to compile a shared library. I am using the latest build of Android Studio (Android Studio 15- #AI-141.2422023 ). In my cpp code, I am using a thirdparty shared library. When writing the Android.mk file, I have first created a PREBUILT_SHARED_LIBRARY with the following code.
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := essentia
LOCAL_SRC_FILES := $(LOCAL_PATH)/../../../essentia-shared/lib/libessentia.so
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/../../../essentia-shared/include/essentia
include $(PREBUILT_SHARED_LIBRARY)
The problem I am facing is that $(LOCAL_PATH) is behaving a bit weirdly. The path it is returning is
jni/jni/../../../essentia-shared/lib/libessentia.so
I have the following questions:
I am not sure, why there are two jni's appended at the front of the path. Also when I tried to print the value of LOCAL_PATH by using $(warning $(LOCAL_PATH)), it prints jni.
Shouldn't $(LOCAL_PATH) return the absolute path? This is even more confusing because at times I got the absolute path using $(LOCAL_PATH).
PS: I am using the terminal internal to Android Studio to run ndk-build
Edit 1: I run the ndk-build from src/main
$(call my-dir) from src/main for src/main/jni/Android.mk results in "jni". On the other hand, LOCAL_SRC_FILES are always treated relative to the LOCAL_PATH, which is "jni". That's how jni/jni appears for your .so.
On the other hand, all …_INCLUDES are treated relative to working directory, which in your case is src/main from where you launched ndk-build. Due to the delicate nature of current directory, it is a good practice to use absolute paths for all include paths.
So, this is the suggested rewrite of this part of your Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := app-lib
LOCAL_SRC_FILES := a.cpp b.cpp
LOCAL_SHARED_LIBRARIES := essentia
include $(BUILD_SHARED_LIBRARY)
LOCAL_PATH += /../../../essentia-shared
include $(CLEAR_VARS)
LOCAL_MODULE := essentia
LOCAL_SRC_FILES := lib/libessentia.so
LOCAL_EXPORT_C_INCLUDES := $(abspath $(LOCAL_PATH)/include/essentia)
include $(PREBUILT_SHARED_LIBRARY)

How to link .so file in android

I have two projects. The output of first one is libtest.so file. Using this shared object file in the 2nd project, i want to generate final android executable, AndroidExe.
I generated libtest.so and its Android.mk is given below
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_CFLAGS := -g
LOCAL_ARM_MODE := arm
LOCAL_MODULE :=test
LOCAL_SRC_FILES := test.c
export LD_LIBRARY_PATH=/data/local/tmp
include $(BUILD_SHARED_LIBRARY)
Here the problem i am facing is that, i don't know how to link this .so file in my final executable project. In this final project, i am using one of the function (sum(a,b)) defined in the .so lib.While do build, showing error undefined reference to 'sum'.Its Android.mk file is given below:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_CFLAGS := -g
LOCAL_ARM_MODE := arm
LOCAL_MODULE :=AndroidExe
LOCAL_SHARED_LIBRARIES := libtest.so
LOCAL_SRC_FILES := AndroidExe.c
include $(BUILD_EXECUTABLE)
just check ndk documentation and try some of the samples.

Include shared dynamic library in jni ndk build

I am trying to compile a ndk module for my android app with a Shared Library provided with these drivers:
http://www.extendo-printer.de/fileadmin/user_upload/extendo/Drivers/X-56-Hengstler-Extendo-LinuxDrivers-S684018-R2-V1_01-FINAL-2009JUL15.zip
I can compile fine with the defaults (using Hello JNI example). But when I add my code the my C file which references a .so library I need to work with I get compile errors stating it can not find the methods defined in the library. When I try to include it in Android.mk in LOCAL_SRC_FILES i get warnings when it builds (unsupported file extension) but it builds, but than my native method call fails (java.lang linkage error). Is there a proper way to include a .so and than reference it's functions in your native C code?
current Android.mk
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := x56-jni
LOCAL_LDLIBS := libExoApi.so
LOCAL_SRC_FILES := x56-jni.c
include $(BUILD_SHARED_LIBRARY)
I tried with LOCAL_SHARED_LIBRARIES as well with same build error. I've also tried adding to LOCAL_SRC_FILES as stated above (LOCAL_SRC_FILES := x56-jni.c libExoApi.so) with a "," and as well as \ syntax.
Update
I've updated Android.mk to:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libExoApi
LOCAL_SRC_FILES := libExoApi.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := x56-jni
LOCAL_LDLIBS := libExoApi.so
LOCAL_SRC_FILES := x56-jni.c
LOCAL_SHARED_LIBRARIES := libExoApi
include $(BUILD_SHARED_LIBRARY)
This fails at:
[exec] Unable to recognise the format of the input file `/var/folders/_6/6jjydzjs457fnpsc9_5cgl980000gn/T//michael/usbserial-generated/libs/armeabi/libExoApi.so'

Linking dependent .so files with ndk-build for Android

I have created a .so file that exposes a native C call to Java via JNI. This works well and I can deploy the app onto my Android system if I just use system libraries in my C code. However, if I want to make calls to functions in other .so files, I cannot get my project to link correctly.
For example, say I have the "libotherso.so" file which contains APIs defined in C that I can call from the "MyJNILibrary.c" code I'm using to generate "libMyJNILibrary.so".
I tried to change my Android.mk file as follows:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := MyJNILibrary
LOCAL_SRC_FILES := MyJNILibrary.c
LOCAL_LDLIBS += -lotherso
include $(BUILD_SHARED_LIBRARY)
But when I call ndk-build on this, I get errors finding -lotherso. Where do I put the "libotherso.so" file so that ndk-build can pick it up?
Thanks for any help you can provide.
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := otherso
LOCAL_SRC_FILES := ../lib/libotherso.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := MyJNILibrary
LOCAL_SRC_FILES := MyJNILibrary.c
LOCAL_SHARED_LIBRARIES := otherso
include $(BUILD_SHARED_LIBRARY)
Note that LOCAL_SRC_FILES is relative to your LOCAL_PATH.
Don't forget to load your dependency before your own JNI library:
static {
System.loadLibrary("otherso");
System.loadLibrary("MyJNILibrary");
}

Categories

Resources