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.
Related
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.
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)
Trying to build a static NDK library using Android's ADT Eclipse tool chain. However, whenever I build with BUILD_STATIC_LIBRARY, no output is produced: I get the message
make: Nothing to be done for `all'."
Any recommendations?
LOCAL_PATH := $(call my-dir)
STL_PATH := "C:/Android/ndk/sources/cxx-stl/gnu-libstdc++/4.6/include"
PLATFORM_INCLUDE := "C:/Android/ndk/sources/cxx-stl/gnu-libstdc++/4.6/libs/armeabi/include"
APP_STL := gnustl_static
include $(CLEAR_VARS)
LOCAL_MODULE := libCore
LOCAL_CPPFLAGS += -std=c++11 -fexceptions -D_OS_ANDROID
LOCAL_LDLIBS := -lGLESv2 -lEGL -lstdc++
LOCAL_C_INCLUDES += $(LOCAL_PATH)/Headers
...
LOCAL_SRC_FILES += Source/Engine/Game.cpp
...
include $(BUILD_STATIC_LIBRARY)
Here is the content of Android.mk file of two-libs sample project from Android NDK.
LOCAL_PATH:= $(call my-dir)
# first lib, which will be built statically
#
include $(CLEAR_VARS)
LOCAL_MODULE := libtwolib-first
LOCAL_SRC_FILES := first.c
include $(BUILD_STATIC_LIBRARY)
# second lib, which will depend on and include the first one
#
include $(CLEAR_VARS)
LOCAL_MODULE := libtwolib-second
LOCAL_SRC_FILES := second.c
LOCAL_STATIC_LIBRARIES := libtwolib-first
include $(BUILD_SHARED_LIBRARY)
You may try building the static library as part of another shared library as shown in the example.
I just did a ndk-build on the two-libs sample project and i could see the .a file along with .so in obj\local\armeabi directory.
Edit:
By default, ndk-build will only build shared libraries and executables, and the modules they depend on. To force a build specify libCore in APP_MODULES as follows.
APP_MODULES := libCore
or in command line as
ndk-build APP_MODULES=libCore
I have some two shared libraries and header for them.
I want to build third shared library using functions from previous two libs.
Have problem with makefile i think. When i try to build receive this:
Android NDK: /cygdrive/d/.../jni/Android.mk: Cannot find module with tag 'shared1' in import path
Android NDK: Are you sure your NDK_MODULE_PATH variable is properly defined ?
Android NDK: The following directories were searched:
Android NDK:
/cygdrive/d/.../jni/Android.mk:36: *** Android NDK: Aborting. . Stop.
structure of my project:
jni/
- myfile.c
- Android.mk
jni/dec/
- lot of header files
jni/enc/
- lot of header files
libs/armeabi/
- shared1.so
- shared2.so
also Android.mk sourse:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_C_INCLUDES := \
$(LOCAL_PATH)/dec \
$(LOCAL_PATH)/enc
LOCAL_SHARED_LIBRARIES := shared1 shared2
LOCAL_MODULE := mylib
LOCAL_SRC_FILES := myfile.c
LOCAL_LDLIBS += -lOpenSLES
LOCAL_LDLIBS += -llog
LOCAL_LDLIBS += -landroid
include $(BUILD_SHARED_LIBRARY)
$(call import-module, shared1)
$(call import-module, shared2)
Take a look to this question: Android JNI APK Packing
You need to give another name for libs/armeabi/ folder to avoid conflicts with NDK build and add the following code before the include $(CLEAR_VARS) statement:
include $(CLEAR_VARS)
LOCAL_MODULE:=shared1
LOCAL_SRC_FILES:=3rdparty_libs/shared1.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE:=shared2
LOCAL_SRC_FILES:=3rdparty_libs/shared2.so
include $(PREBUILT_SHARED_LIBRARY)
As I understand it, the correct method is to use ndk-build and not invoking the compiler directly.
In Android.mk you need to specify a module for each static library you want to compile, and then specify that your shared library should use it.
Example of a modified Android.mk file of the hello-jni sample project:
LOCAL_PATH := $(call my-dir)
# Define vars for library that will be build statically.
include $(CLEAR_VARS)
LOCAL_MODULE := <module_name>
LOCAL_C_INCLUDES := <header_files_path>
LOCAL_SRC_FILES := <list_of_src_files>
# Optional compiler flags.
LOCAL_LDLIBS = -lz -lm
LOCAL_CFLAGS = -Wall -pedantic -std=c99 -g
include $(BUILD_STATIC_LIBRARY)
# First lib, which will be built statically.
include $(CLEAR_VARS)
LOCAL_MODULE := hello-jni
LOCAL_STATIC_LIBRARIES := <module_name>
LOCAL_C_INCLUDES := <header_files_path>
LOCAL_SRC_FILES := hello-jni.c
include $(BUILD_SHARED_LIBRARY)
If you want control over which modules to compile when you run ndk-build you can create create a Application.mk file (in the same directory as Android.mk) and list all the modules as in the following example:
APP_MODULES := <module_name_1> <module_name_2> ... <module_name_n>
I think it Helps you
I am trying to include static cpp library in android. This library is already compiled(on mac os) and i have its include files.
Here is my Android.mk file
LOCAL_PATH := $(call my-dir)
include $(call all-subdir-makefiles)
include $(CLEAR_VARS)
LOCAL_MODULE:= utils
LOCAL_SRC_FILES:= libUtils.a
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)/utils
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := sample
LOCAL_SRC_FILES := sample_cpp.cpp
LOCAL_EXPORT_C_INCLUDES := $(LOCAL_PATH)
LOCAL_STATIC_LIBRARIES := utils
LOCAL_LDLIBS := -llog
include $(BUILD_SHARED_LIBRARY)
and here is Application.mk file
APP_STL := stlport_static
APP_CPPFLAGS = -fexceptions
but whenever it try to compile it using NDK i get the error
(Path of file)/libUtils.a: file not recognized: File format not recognized
collect2: ld returned 1 exit status
From the comments and so on it sounds like you trying to use a non arm version of the library. You should build the library with the ndk. The documentation has even documentation on how to do that.
For example building sigc++ could be like (from a project of mine, where sigc++ resides in the sigc++ subdirectory)
# SIGC++ Library built as static library
LOCAL_MODULE := sigc
LOCAL_PATH = $(CURRENT_DIR)
LOCAL_CPP_EXTENSION := .cc
LOCAL_SRC_FILES := sigc++/signal.cc sigc++/signal_base.cc sigc++/trackable.cc
LOCAL_SRC_FILES += sigc++/functors/slot_base.cc sigc++/adaptors/lambda/lambda.cc
LOCAL_SRC_FILES += sigc++/connection.cc sigc++/functors/slot.cc
LOCAL_C_INCLUDES := sigc++
include $(BUILD_STATIC_LIBRARY)
But you should really read how the compiling linking works. I am afraid building for android with ndk is more low level than using Xcode or Msvc.